From 822c53a55c4c99d8cc894bc2d3f27ee5fc9d79fb Mon Sep 17 00:00:00 2001
From: Sri Hari <94112314+Srihari2222@users.noreply.github.com>
Date: Mon, 10 Mar 2025 19:58:58 +0530
Subject: [PATCH 1/9] Sri Hari: Batch-6/Neetcode-150/Added-hints (#3909)
* Batch-6/Neetcode-150/Added-hints
* Batch-6/Neetcode-150/Added-hints
* Batch-6/Neetcode-150/Added-hints
* Batch-6/Neetcode-150/Added-hints
* Batch-6/Neetcode-150/Added-hints
---
articles/counting-bits.md | 26 ++++++----
articles/insert-new-interval.md | 12 +++--
articles/merge-intervals.md | 4 +-
articles/plus-one.md | 14 +++---
articles/set-zeroes-in-matrix.md | 2 +-
articles/spiral-matrix.md | 12 +++--
articles/string-encode-and-decode.md | 8 ++--
.../subarrays-with-k-different-integers.md | 2 +-
hints/burst-balloons.md | 39 +++++++++++++++
hints/buy-and-sell-crypto-with-cooldown.md | 39 +++++++++++++++
hints/coin-change-ii.md | 39 +++++++++++++++
hints/count-paths.md | 39 +++++++++++++++
hints/count-squares.md | 39 +++++++++++++++
hints/count-subsequences.md | 39 +++++++++++++++
hints/counting-bits.md | 31 ++++++++++++
hints/edit-distance.md | 39 +++++++++++++++
hints/gas-station.md | 31 ++++++++++++
hints/hand-of-straights.md | 31 ++++++++++++
hints/insert-new-interval.md | 31 ++++++++++++
hints/interleaving-string.md | 39 +++++++++++++++
hints/jump-game-ii.md | 39 +++++++++++++++
hints/jump-game.md | 39 +++++++++++++++
hints/longest-common-subsequence.md | 31 ++++++++++++
hints/longest-increasing-path-in-matrix.md | 23 +++++++++
hints/longest-increasing-subsequence.md | 47 +++++++++++++++++++
hints/maximum-product-subarray.md | 31 ++++++++++++
hints/maximum-subarray.md | 39 +++++++++++++++
hints/meeting-schedule-ii.md | 39 +++++++++++++++
hints/meeting-schedule.md | 31 ++++++++++++
hints/merge-intervals.md | 39 +++++++++++++++
hints/merge-triplets-to-form-target.md | 31 ++++++++++++
hints/minimum-interval-including-query.md | 31 ++++++++++++
hints/missing-number.md | 39 +++++++++++++++
hints/multiply-strings.md | 39 +++++++++++++++
hints/non-cyclical-number.md | 23 +++++++++
hints/non-overlapping-intervals.md | 39 +++++++++++++++
hints/number-of-one-bits.md | 31 ++++++++++++
hints/partition-equal-subset-sum.md | 39 +++++++++++++++
hints/partition-labels.md | 31 ++++++++++++
hints/plus-one.md | 23 +++++++++
hints/pow-x-n.md | 39 +++++++++++++++
hints/regular-expression-matching.md | 39 +++++++++++++++
hints/reverse-bits.md | 31 ++++++++++++
hints/reverse-integer.md | 31 ++++++++++++
hints/rotate-matrix.md | 31 ++++++++++++
hints/set-zeroes-in-matrix.md | 39 +++++++++++++++
hints/single-number.md | 39 +++++++++++++++
hints/spiral-matrix.md | 31 ++++++++++++
hints/string-encode-and-decode.md | 2 +-
hints/sum-of-two-integers.md | 39 +++++++++++++++
hints/target-sum.md | 31 ++++++++++++
hints/valid-parenthesis-string.md | 39 +++++++++++++++
hints/word-break.md | 31 ++++++++++++
53 files changed, 1594 insertions(+), 28 deletions(-)
create mode 100644 hints/burst-balloons.md
create mode 100644 hints/buy-and-sell-crypto-with-cooldown.md
create mode 100644 hints/coin-change-ii.md
create mode 100644 hints/count-paths.md
create mode 100644 hints/count-squares.md
create mode 100644 hints/count-subsequences.md
create mode 100644 hints/counting-bits.md
create mode 100644 hints/edit-distance.md
create mode 100644 hints/gas-station.md
create mode 100644 hints/hand-of-straights.md
create mode 100644 hints/insert-new-interval.md
create mode 100644 hints/interleaving-string.md
create mode 100644 hints/jump-game-ii.md
create mode 100644 hints/jump-game.md
create mode 100644 hints/longest-common-subsequence.md
create mode 100644 hints/longest-increasing-path-in-matrix.md
create mode 100644 hints/longest-increasing-subsequence.md
create mode 100644 hints/maximum-product-subarray.md
create mode 100644 hints/maximum-subarray.md
create mode 100644 hints/meeting-schedule-ii.md
create mode 100644 hints/meeting-schedule.md
create mode 100644 hints/merge-intervals.md
create mode 100644 hints/merge-triplets-to-form-target.md
create mode 100644 hints/minimum-interval-including-query.md
create mode 100644 hints/missing-number.md
create mode 100644 hints/multiply-strings.md
create mode 100644 hints/non-cyclical-number.md
create mode 100644 hints/non-overlapping-intervals.md
create mode 100644 hints/number-of-one-bits.md
create mode 100644 hints/partition-equal-subset-sum.md
create mode 100644 hints/partition-labels.md
create mode 100644 hints/plus-one.md
create mode 100644 hints/pow-x-n.md
create mode 100644 hints/regular-expression-matching.md
create mode 100644 hints/reverse-bits.md
create mode 100644 hints/reverse-integer.md
create mode 100644 hints/rotate-matrix.md
create mode 100644 hints/set-zeroes-in-matrix.md
create mode 100644 hints/single-number.md
create mode 100644 hints/spiral-matrix.md
create mode 100644 hints/sum-of-two-integers.md
create mode 100644 hints/target-sum.md
create mode 100644 hints/valid-parenthesis-string.md
create mode 100644 hints/word-break.md
diff --git a/articles/counting-bits.md b/articles/counting-bits.md
index 514bef953..ac8139aba 100644
--- a/articles/counting-bits.md
+++ b/articles/counting-bits.md
@@ -124,8 +124,10 @@ class Solution {
### Time & Space Complexity
-* Time complexity: $O(n)$
-* Space complexity: $O(1)$
+* Time complexity: $O(n \log n)$
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(n)$ space for the output array.
---
@@ -248,8 +250,10 @@ class Solution {
### Time & Space Complexity
-* Time complexity: $O(n)$
-* Space complexity: $O(1)$
+* Time complexity: $O(n \log n)$
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(n)$ space for the output array.
---
@@ -338,8 +342,10 @@ class Solution {
### Time & Space Complexity
-* Time complexity: $O(n)$
-* Space complexity: $O(1)$
+* Time complexity: $O(n \log n)$
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(n)$ space for the output array.
---
@@ -470,7 +476,9 @@ class Solution {
### Time & Space Complexity
* Time complexity: $O(n)$
-* Space complexity: $O(1)$
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(n)$ space for the output array.
---
@@ -567,4 +575,6 @@ class Solution {
### Time & Space Complexity
* Time complexity: $O(n)$
-* Space complexity: $O(1)$
\ No newline at end of file
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(n)$ space for the output array.
\ No newline at end of file
diff --git a/articles/insert-new-interval.md b/articles/insert-new-interval.md
index e35159e6e..367a09391 100644
--- a/articles/insert-new-interval.md
+++ b/articles/insert-new-interval.md
@@ -221,7 +221,9 @@ class Solution {
### Time & Space Complexity
* Time complexity: $O(n)$
-* Space complexity: $O(1)$
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(n)$ space for the output list.
---
@@ -515,7 +517,9 @@ class Solution {
### Time & Space Complexity
* Time complexity: $O(n)$
-* Space complexity: $O(1)$
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(n)$ space for the output list.
---
@@ -708,4 +712,6 @@ class Solution {
### Time & Space Complexity
* Time complexity: $O(n)$
-* Space complexity: $O(1)$
\ No newline at end of file
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(n)$ space for the output list.
\ No newline at end of file
diff --git a/articles/merge-intervals.md b/articles/merge-intervals.md
index 56f8a6313..4ff97b569 100644
--- a/articles/merge-intervals.md
+++ b/articles/merge-intervals.md
@@ -169,7 +169,9 @@ class Solution {
### Time & Space Complexity
* Time complexity: $O(n \log n)$
-* Space complexity: $O(1)$ or $O(n)$ depending on the sorting algorithm.
+* Space complexity:
+ * $O(1)$ or $O(n)$ space depending on the sorting algorithm.
+ * $O(n)$ for the output list.
---
diff --git a/articles/plus-one.md b/articles/plus-one.md
index 242d171fb..4b51b5b0c 100644
--- a/articles/plus-one.md
+++ b/articles/plus-one.md
@@ -139,7 +139,7 @@ class Solution {
---
-## 2. Iteration
+## 2. Iteration - I
::tabs-start
@@ -148,7 +148,7 @@ class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
one = 1
i = 0
- digits = digits[::-1]
+ digits.reverse()
while one:
if i < len(digits):
@@ -161,7 +161,9 @@ class Solution:
digits.append(one)
one = 0
i += 1
- return digits[::-1]
+
+ digits.reverse()
+ return digits
```
```java
@@ -344,11 +346,11 @@ class Solution {
### Time & Space Complexity
* Time complexity: $O(n)$
-* Space complexity: $O(1)$
+* Space complexity: $O(1)$ or $O(n)$ depending on the language.
---
-## 3. Iteration (Optimal)
+## 3. Iteration - II
::tabs-start
@@ -479,4 +481,4 @@ class Solution {
### Time & Space Complexity
* Time complexity: $O(n)$
-* Space complexity: $O(1)$
\ No newline at end of file
+* Space complexity: $O(n)$
\ No newline at end of file
diff --git a/articles/set-zeroes-in-matrix.md b/articles/set-zeroes-in-matrix.md
index 905883b5c..5a265e1f5 100644
--- a/articles/set-zeroes-in-matrix.md
+++ b/articles/set-zeroes-in-matrix.md
@@ -212,7 +212,7 @@ class Solution {
### Time & Space Complexity
-* Time complexity: $O(m * n)$
+* Time complexity: $O((m * n) * (m + n))$
* Space complexity: $O(m * n)$
> Where $m$ is the number of rows and $n$ is the number of columns.
diff --git a/articles/spiral-matrix.md b/articles/spiral-matrix.md
index b9719b928..7935874fc 100644
--- a/articles/spiral-matrix.md
+++ b/articles/spiral-matrix.md
@@ -203,7 +203,9 @@ class Solution {
### Time & Space Complexity
* Time complexity: $O(m * n)$
-* Space complexity: $O(min(m, n))$
+* Space complexity:
+ * $O(min(m, n))$ space for recursion stack.
+ * $O(m * n)$ space for the output list.
> Where $m$ is the number of rows and $n$ is the number of columns.
@@ -467,7 +469,9 @@ class Solution {
### Time & Space Complexity
* Time complexity: $O(m * n)$
-* Space complexity: $O(1)$
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(m * n)$ space for the output list.
> Where $m$ is the number of rows and $n$ is the number of columns.
@@ -655,6 +659,8 @@ class Solution {
### Time & Space Complexity
* Time complexity: $O(m * n)$
-* Space complexity: $O(1)$
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(m * n)$ space for the output list.
> Where $m$ is the number of rows and $n$ is the number of columns.
\ No newline at end of file
diff --git a/articles/string-encode-and-decode.md b/articles/string-encode-and-decode.md
index c0cad7e12..b60d5115e 100644
--- a/articles/string-encode-and-decode.md
+++ b/articles/string-encode-and-decode.md
@@ -286,8 +286,8 @@ class Solution {
### Time & Space Complexity
-* Time complexity: $O(m)$ for $encode()$ and $decode()$.
-* Space complexity: $O(n)$ for $encode()$ and $decode()$.
+* Time complexity: $O(m)$ for each $encode()$ and $decode()$ function calls.
+* Space complexity: $O(m + n)$ for each $encode()$ and $decode()$ function calls.
> Where $m$ is the sum of lengths of all the strings and $n$ is the number of strings.
@@ -510,7 +510,7 @@ class Solution {
### Time & Space Complexity
-* Time complexity: $O(m)$ for $encode()$ and $decode()$.
-* Space complexity: $O(1)$ for $encode()$ and $decode()$.
+* Time complexity: $O(m)$ for each $encode()$ and $decode()$ function calls.
+* Space complexity: $O(m + n)$ for each $encode()$ and $decode()$ function calls.
> Where $m$ is the sum of lengths of all the strings and $n$ is the number of strings.
\ No newline at end of file
diff --git a/articles/subarrays-with-k-different-integers.md b/articles/subarrays-with-k-different-integers.md
index 26328205c..a2e24a470 100644
--- a/articles/subarrays-with-k-different-integers.md
+++ b/articles/subarrays-with-k-different-integers.md
@@ -246,7 +246,7 @@ class Solution {
---
-## 3. Slidingt Window (One Pass) - I
+## 3. Sliding Window (One Pass) - I
::tabs-start
diff --git a/hints/burst-balloons.md b/hints/burst-balloons.md
new file mode 100644
index 000000000..c553a4f8e
--- /dev/null
+++ b/hints/burst-balloons.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(n ^ 3)
time and O(n ^ 2)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ Try to simulate the process recursively by passing the array to the recursive function. At each step, iterate through the array, pop an element, and recursively apply the same process to the two subarrays on both sides of the popped element, returning the maximum result from all recursive paths. This approach is exponential. Can you think of a way to optimize it? Maybe you should consider observing the subproblems instead of modifying the array.
+
+
+
+
+
+ Hint 2
+
+ Instead of passing the array, we can pass the range of indices l
and r
that need to be processed. We pad the input array with 1
s on both sides for easier computation, but l
and r
represent the first and last indices of the original input array. Can you think of a reverse engineering approach for popping elements?
+
+
+
+
+
+ Hint 3
+
+ We determine the result by considering each element as the last one to be popped in the current range. For each element, we calculate its value by multiplying it with the elements at l - 1
and r + 1
, then recursively solve the subproblems for the ranges (l, i - 1)
and (i + 1, r)
, where i
is the current element in the given range. Can you think of a way to optimize and avoid redundant calculations?
+
+
+
+
+
+ Hint 4
+
+ We can use memoization to cache the results of recursive calls and avoid redundant calculations. A hash map or a 2D
array can be used to store results since the recursive function parameters l
and r
are within the range of the input array size.
+
+
\ No newline at end of file
diff --git a/hints/buy-and-sell-crypto-with-cooldown.md b/hints/buy-and-sell-crypto-with-cooldown.md
new file mode 100644
index 000000000..84988bd54
--- /dev/null
+++ b/hints/buy-and-sell-crypto-with-cooldown.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(n)
time and O(n)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ Try to think in terms of recursion and visualize it as a decision tree. Can you determine the possible decisions at each recursion step? Also, can you identify the base cases and the essential information that needs to be tracked during recursion?
+
+
+
+
+
+ Hint 2
+
+ At each recursion step, we can buy only if we haven't already bought a coin, or we can sell if we own one. When buying, we subtract the coin value, and when selling, we add it. We explore all possible buying and selling options recursively, iterating through the coins from left to right using index i
. For the cooldown condition, if we buy a coin, we increment the index i
by two.
+
+
+
+
+
+ Hint 3
+
+ We can use a boolean variable canBuy
to indicate whether buying is allowed at the current recursive step. If we go out of bounds, we return 0
. This approach is exponential. Can you think of a way to optimize it?
+
+
+
+
+
+ Hint 4
+
+ We can use memoization to cache the results of recursive calls and avoid recalculations. A hash map or a 2D
array can be used to store these results.
+
+
\ No newline at end of file
diff --git a/hints/coin-change-ii.md b/hints/coin-change-ii.md
new file mode 100644
index 000000000..3f18a6318
--- /dev/null
+++ b/hints/coin-change-ii.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(n * a)
time and O(n * a)
space, where n
is the number of coins and a
is the given amount.
+
+
+
+
+
+ Hint 1
+
+ As we need to find the total number of combinations, think in terms of recursion and visualize it as a decision tree where multiple coin choices are available at each recursion step. Can you determine a way to allow picking the same coin multiple times? Maybe you should consider the decisions made at each recursion step.
+
+
+
+
+
+ Hint 2
+
+ The given coins are unique. We recursively iterate through the coins array using index i
, tracking the collected amount along the current path. At each step, we can either skip the current coin or pick it, ensuring the total does not exceed the target. To allow picking the same coin multiple times, we recurse with the same index but an updated amount, generating different combinations.
+
+
+
+
+
+ Hint 3
+
+ If we reach the target amount, we return 1
. The recursion stops if the index goes out of bounds. We count all possible ways and return the total. This approach is exponential. Can you think of a way to optimize it? Maybe you should consider an approach to avoid redundant computations.
+
+
+
+
+
+ Hint 4
+
+ We can use memoization to cache the results of recursive calls and avoid redundant computations. A hash map or a 2D
array can be used to store these results.
+
+
\ No newline at end of file
diff --git a/hints/count-paths.md b/hints/count-paths.md
new file mode 100644
index 000000000..299793547
--- /dev/null
+++ b/hints/count-paths.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(m * n)
time and O(m * n)
space, where m
is the number of rows and n
is the number of columns in the grid.
+
+
+
+
+
+ Hint 1
+
+ Try to think in terms of recursion and visualize it as a decision tree, where we have two choices at each step. Can you determine the base condition and recurrence relation?
+
+
+
+
+
+ Hint 2
+
+ We recursively traverse the grid using row i
and column j
. At each step, we explore both possibilities: moving down or moving right, ensuring we do not go out of bounds. If we reach the bottom-right cell, we return 1
.
+
+
+
+
+
+ Hint 3
+
+ This approach has exponential complexity. Can you think of a way to optimize the recursion? Maybe you should consider using a dynamic programming approach.
+
+
+
+
+
+ Hint 4
+
+ We can use memoization to cache the results of recursive calls and avoid recalculations. A hash map or a 2D
array can be used to store these results.
+
+
\ No newline at end of file
diff --git a/hints/count-squares.md b/hints/count-squares.md
new file mode 100644
index 000000000..69b289bdb
--- /dev/null
+++ b/hints/count-squares.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(1)
time for each add()
call, O(n)
time for each count()
call, and O(n)
space, where n
is the total number of points.
+
+
+
+
+
+ Hint 1
+
+ Initially, we can store the points in a global list for the add()
call. For the count()
call, a brute force approach would use three nested loops to check other points except for the query point, resulting in an O(n^3)
time solution. Can you think of a better way? Maybe you should consider the observation that can be drawn from the diagonal of a square.
+
+
+
+
+
+ Hint 2
+
+ In a square's diagonal, the absolute difference between the x-coordinates is equal to the absolute difference between the y-coordinates of the two endpoints, and neither difference can be zero. Using these two points, we can determine the other diagonal endpoints.
+
+
+
+
+
+ Hint 3
+
+ We store points in a hash map instead of a list for O(1)
lookups, treating duplicate points as one while tracking their frequencies. For the count()
function, we iterate through points that, along with the query point, can form a diagonal. Let the query point be (qx, qy)
and the other point be (x, y)
, ensuring they form a diagonal. What could be the other two points? Maybe you should consider the points forming a right-to-left diagonal, treating (qx, qy)
as the top-right corner.
+
+
+
+
+
+ Hint 4
+
+ The other two points are point1 (x, qy)
and point2 (qx, y)
. For counting, we simply add count of point1 * count of point2
to the result res
.
+
+
\ No newline at end of file
diff --git a/hints/count-subsequences.md b/hints/count-subsequences.md
new file mode 100644
index 000000000..53a37dcee
--- /dev/null
+++ b/hints/count-subsequences.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(m * n)
time and O(m * n)
space, where m
is the length of the string s
and n
is the length of the string t
.
+
+
+
+
+
+ Hint 1
+
+ Try to think in terms of recursion and visualize it as a decision tree, as we need to explore all subsequences of s
. Can you determine the possible decisions at each recursion step?
+
+
+
+
+
+ Hint 2
+
+ We recursively iterate through the strings using indices i
and j
for s
and t
, respectively. At each recursion step, we can either skip the current character of s
or include it in the current path if it matches the current character of t
. Can you determine the base conditions for this recursive function?
+
+
+
+
+
+ Hint 3
+
+ If index j
goes out of bounds, we return 1
as a valid subsequence is found. If index i
goes out of bounds first, we return 0
. At each recursion step, we return the sum of both paths. This approach is exponential. Can you think of a way to optimize it?
+
+
+
+
+
+ Hint 4
+
+ We can use memoization to cache the results of recursive calls and avoid redundant computations. A hash map or a 2D
array can be used to store these results.
+
+
\ No newline at end of file
diff --git a/hints/counting-bits.md b/hints/counting-bits.md
new file mode 100644
index 000000000..45188a165
--- /dev/null
+++ b/hints/counting-bits.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(n)
time and O(n)
space, where n
is the given integer.
+
+
+
+
+
+ Hint 1
+
+ A straightforward approach would be to iterate from 0
to n
using i
, and for each i
, iterate through its bits to count the number of set bits. This would result in an O(n \log n)
approach. Can you think of a better way? Maybe you should try identifying a pattern by observing the bitwise representation of consecutive numbers.
+
+
+
+
+
+ Hint 2
+
+ For example, to compute set bits for 7
, add 1
to the count of set bits in 3
, which was previously computed by adding 1
to the count of set bits in 1
. Observing the pattern, for numbers less than 4
, add 1
to the count from two positions before. For numbers less than 8
, add 1
to the count from four positions before. Can you derive a dynamic programming relation from this?
+
+
+
+
+
+ Hint 3
+
+ We find an offset for the current number based on the number before offset
positions. The dynamic programming relation is dp[i] = 1 + dp[i - offset]
, where dp[i]
represents the number of set bits in i
. The offset starts at 1
and updates when encountering a power of 2
. To simplify the power of 2
check, if offset * 2
equals the current number, we update offset
to the current number.
+
+
\ No newline at end of file
diff --git a/hints/edit-distance.md b/hints/edit-distance.md
new file mode 100644
index 000000000..277fa3cbe
--- /dev/null
+++ b/hints/edit-distance.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(m * n)
time and O(m * n)
space, where m
and n
are the lengths of the strings word1
and word2
, respectively.
+
+
+
+
+
+ Hint 1
+
+ Try to think in terms of recursion and visualize it as a decision tree, as we have choices at each recursion step. Can you determine the recurrence relation and base cases?
+
+
+
+
+
+ Hint 2
+
+ We recursively iterate through the strings using indices i
and j
for word1
and word2
, respectively. If the characters at the current indices match, we increment both indices without counting an operation. Otherwise, we have three choices: insert the character at the current index of word1
(increment j
), delete the current character of word1
(increment i
), or replace the character at index i
in word1
(increment both i
and j
).
+
+
+
+
+
+ Hint 3
+
+ If index i
goes out of bounds, we return the number of remaining characters in word2
(using insert operations). If index j
goes out of bounds, we return the number of remaining characters in word1
(using delete operations). At each step, we return the minimum operation path. This approach is exponential. Can you think of a way to optimize it?
+
+
+
+
+
+ Hint 4
+
+ We can use memoization to cache the results and avoid redundant calculations. A hash map or a 2D
array can be used to store these results.
+
+
\ No newline at end of file
diff --git a/hints/gas-station.md b/hints/gas-station.md
new file mode 100644
index 000000000..52464072d
--- /dev/null
+++ b/hints/gas-station.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(n)
time and O(1)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ A brute force approach would be to start at each gas station, simulate the process, and return the index where completing the circuit is possible. This would be an O(n^2)
time solution. Can you think of a better way? Maybe a greedy approach works.
+
+
+
+
+
+ Hint 2
+
+ We can immediately return -1
if sum(gas) < sum(cost)
, as completing the circuit is impossible due to insufficient gas. Otherwise, a solution always exists because the total gas is sufficient to cover the total cost, meaning there must be a valid starting point that allows completing the circuit.
+
+
+
+
+
+ Hint 3
+
+ We start with a variable total
to track the gas balance and initialize the result index to 0
. As we iterate through the array with index i
, we accumulate the difference (gas[i] - cost[i])
. If total
becomes negative at any index, we reset it to 0
and update the result index to (i + 1)
.
+
+
\ No newline at end of file
diff --git a/hints/hand-of-straights.md b/hints/hand-of-straights.md
new file mode 100644
index 000000000..1a35e0287
--- /dev/null
+++ b/hints/hand-of-straights.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(nlogn)
time and O(n)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ It is observed that to form a group, the minimum value should be the starting value of the group. Additionally, the minimum value in the array serves as the starting value for one or more groups based on its frequency. Can you think of an efficient way to determine the frequencies of array elements? Maybe a specific data structure can be useful here.
+
+
+
+
+
+ Hint 2
+
+ We can use a hash map to store the elements along with their frequencies. Additionally, we sort the given array. Then, we iterate through the sorted array and try to form groups by decrementing the frequency count. If we fail to form a group at any step, we immediately return false
. Can you think why this works?
+
+
+
+
+
+ Hint 3
+
+ Sorting ensures we start with the smallest available value, while the hash map helps track element availability using frequency counts. At each step, we pick the smallest available value x
and attempt to form a group from x
to x + groupSize - 1
. If all elements are present based on their frequency counts, we decrement their counts as we iterate. If we successfully form all groups, we return true
; otherwise, we return false
.
+
+
\ No newline at end of file
diff --git a/hints/insert-new-interval.md b/hints/insert-new-interval.md
new file mode 100644
index 000000000..a807b4c61
--- /dev/null
+++ b/hints/insert-new-interval.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(n)
time and O(1)
extra space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ The given intervals are non-overlapping and sorted in ascending order based on the start value. Try to visualize them as line segments and consider how a new interval can be inserted. Maybe you should analyze different cases of inserting a new interval.
+
+
+
+
+
+ Hint 2
+
+ First, we append all intervals to the output list that have an end value smaller than the start value of the new interval. Then, we encounter one of three cases: we have appended all intervals, we reach an interval whose start value is greater than the new interval’s end, or we find an overlapping interval. Can you think of a way to handle these cases efficiently?
+
+
+
+
+
+ Hint 3
+
+ We iterate through the remaining intervals, updating the new interval if its end value is greater than or equal to the current interval's start value. We adjust the start and end of the new interval to the minimum and maximum values, respectively. After this, any remaining intervals are appended to the output list, and we return the result.
+
+
\ No newline at end of file
diff --git a/hints/interleaving-string.md b/hints/interleaving-string.md
new file mode 100644
index 000000000..16a8c100a
--- /dev/null
+++ b/hints/interleaving-string.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(m * n)
time and O(m * n)
space, where m
is the length of the string s1
and n
is the length of the string s2
.
+
+
+
+
+
+ Hint 1
+
+ If the sum of the characters in s1
and s2
does not equal s3
, we return false
. Think in terms of recursion and visualize it as a decision tree, where we explore different combinations of portions from both strings. Can you determine the possible decisions at each recursion step?
+
+
+
+
+
+ Hint 2
+
+ We recursively iterate through the strings using indices i
, j
, and k
for s1
, s2
, and s3
, respectively. At each step, we extend the current path in two directions based on whether the k
-th character of s3
matches the current character of s1
or s2
. If any path returns true
, we immediately return true
. If k
goes out of bounds, it means we have successfully formed the interleaved string, so we return true
.
+
+
+
+
+
+ Hint 3
+
+ This approach is exponential. Can you think of a way to optimize it? Since k
depends on i
and j
, it can be treated as a constant, as we can derive k
using i + j
.
+
+
+
+
+
+ Hint 4
+
+ We can use memoization to cache the results of recursive calls and avoid redundant computations. Treating i
and j
as states, we can use a hash map or a 2D
array to store the results.
+
+
\ No newline at end of file
diff --git a/hints/jump-game-ii.md b/hints/jump-game-ii.md
new file mode 100644
index 000000000..4c7c41e30
--- /dev/null
+++ b/hints/jump-game-ii.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(n)
time and O(1)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ A brute force approach would be to recursively explore all paths from index 0
to its reachable indices, then process those indices similarly and return the minimum steps to reach the last index. This would be an exponential approach. Can you think of a better way? Maybe a greedy approach works.
+
+
+
+
+
+ Hint 2
+
+ We maintain two pointers, l
and r
, initially set to 0
, representing the range of reachable indices. At each step, we iterate through the indices in the range l
to r
and determine the farthest index that can be reached from the current range.
+
+
+
+
+
+ Hint 3
+
+ We then update the pointers l
and r
to the next range, setting l
to r + 1
and r
to the farthest index reachable from the current range. We continue this process until the pointers go out of bounds.
+
+
+
+
+
+ Hint 4
+
+ The number of steps taken represents the minimum steps required to reach the last index, as it is guaranteed that we can reach it.
+
+
\ No newline at end of file
diff --git a/hints/jump-game.md b/hints/jump-game.md
new file mode 100644
index 000000000..91e7092c9
--- /dev/null
+++ b/hints/jump-game.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(n)
time and O(1)
space, where n
is the size of input array.
+
+
+
+
+
+ Hint 1
+
+ A brute force approach would be to recursively explore all paths from index 0
to its reachable indices, then process those indices similarly, returning true
if we reach the last index. This would be an exponential approach. Can you think of a better way? Maybe a greedy approach works.
+
+
+
+
+
+ Hint 2
+
+ Instead of processing the array from index 0
, start from the last index. Let the target index be goal = n - 1
. Iterate in reverse from index n - 2
.
+
+
+
+
+
+ Hint 3
+
+ At each iteration, we check whether the current index can reach goal
. If it can, we update goal
to the current index, as reaching the current index means we can also reach the goal
.
+
+
+
+
+
+ Hint 4
+
+ To determine if we can reach the last index, the goal
should be 0
after the iteration. Otherwise, reaching the last index is not possible.
+
+
\ No newline at end of file
diff --git a/hints/longest-common-subsequence.md b/hints/longest-common-subsequence.md
new file mode 100644
index 000000000..d25df25e5
--- /dev/null
+++ b/hints/longest-common-subsequence.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(m * n)
time and O(m * n)
space, where m
is the length of the string text1
and n
is the length of the string text2
.
+
+
+
+
+
+ Hint 1
+
+ Try to think in terms of recursion and visualize it as a decision tree. Can you determine the possible decisions at each step? Maybe you should consider iterating through both strings recursively at the same time.
+
+
+
+
+
+ Hint 2
+
+ At each recursion step, we have two choices: if the characters at the current indices of both strings match, we move both indices forward and extend the subsequence. Otherwise, we explore two paths by advancing one index at a time and recursively finding the longest subsequence. We return the maximum length between these two choices. This approach is exponential. Can you think of a way to optimize it?
+
+
+
+
+
+ Hint 3
+
+ We return 0
if either index goes out of bounds. To optimize, we can use memoization to cache recursive call results and avoid redundant calculations. A hash map or a 2D
array can be used to store these results.
+
+
\ No newline at end of file
diff --git a/hints/longest-increasing-path-in-matrix.md b/hints/longest-increasing-path-in-matrix.md
new file mode 100644
index 000000000..8008fe73f
--- /dev/null
+++ b/hints/longest-increasing-path-in-matrix.md
@@ -0,0 +1,23 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(m * n)
time and O(m * n)
space, where m
is the number of rows and n
is the number of columns in the given matrix.
+
+
+
+
+
+ Hint 1
+
+ If we move from one cell to an adjacent cell with a greater value, we won't revisit a cell, as the path is strictly increasing. A brute force approach would be to run a dfs
from every cell and return the longest path found. This approach is exponential. Can you think of a way to optimize it to avoid redundant calculations?
+
+
+
+
+
+ Hint 2
+
+ We can use memoization to cache the results of recursive calls and avoid redundant computations. A hash map or a 2D
array can be used to store these results.
+
+
\ No newline at end of file
diff --git a/hints/longest-increasing-subsequence.md b/hints/longest-increasing-subsequence.md
new file mode 100644
index 000000000..36a4e3e78
--- /dev/null
+++ b/hints/longest-increasing-subsequence.md
@@ -0,0 +1,47 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(n ^ 2)
time and O(n ^ 2)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ A subsequence is formed by selecting elements while maintaining their order. Using recursion, we can generate all subsequences. The recursive function returns the length of the longest increasing subsequence up to index i
, processing from left to right. At each step, we decide whether to include or exclude the current element.
+
+
+
+
+
+ Hint 2
+
+ Since the sequence must be increasing, we represent choices by adding 1
when including an element and 0
when excluding it. In recursion, how can we ensure the current element is greater than the previous one? Perhaps additional information is needed to process it.
+
+
+
+
+
+ Hint 3
+
+ We can store the index of the previously chosen element as j
, making it easier to process the current element at index i
. If and only if j == -1
or nums[i] > nums[j]
, we include the current element and extend the recursive path. Can you determine the recurrence relation? At most, two recursive calls are made at each recursion step.
+
+
+
+
+
+ Hint 4
+
+ We stop the recursion when index i
goes out of bounds and return 0
since no more elements can be added. The initial recursion call starts with j = -1
. At each step, we include the current element if it is greater than the previous one and continue the recursion, or we exclude it and explore the next possibility. We return the maximum value obtained from both paths.
+
+
+
+
+
+ Hint 5
+
+ The time complexity of this approach is exponential. We can use memoization to store results of recursive calls and avoid recalculations. A hash map or a 2D
array can be used to cache these results.
+
+
\ No newline at end of file
diff --git a/hints/maximum-product-subarray.md b/hints/maximum-product-subarray.md
new file mode 100644
index 000000000..d46997d32
--- /dev/null
+++ b/hints/maximum-product-subarray.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(n)
time and O(1)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ A brute force solution would be to find the product for every subarray and then return the maximum among all the products. This would be an O(n ^ 2)
approach. Can you think of a better way? Maybe you should think of a dynamic programming approach.
+
+
+
+
+
+ Hint 2
+
+ Try to identify a pattern by finding the maximum product for an array with two elements and determining what values are needed when increasing the array size to three. Perhaps you only need two values when introducing a new element.
+
+
+
+
+
+ Hint 3
+
+ We maintain both the minimum and maximum product values and update them when introducing a new element by considering three cases: starting a new subarray, multiplying with the previous max product, or multiplying with the previous min product. The max product is updated to the maximum of these three, while the min product is updated to the minimum. We also track a global max product for the result. This approach is known as Kadane's algorithm.
+
+
\ No newline at end of file
diff --git a/hints/maximum-subarray.md b/hints/maximum-subarray.md
new file mode 100644
index 000000000..f8071b628
--- /dev/null
+++ b/hints/maximum-subarray.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(n)
time and O(1)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ A brute force approach would be to compute the sum of every subarray and return the maximum among them. This would be an O(n^2)
approach. Can you think of a better way? Maybe you should consider a dynamic programming-based approach.
+
+
+
+
+
+ Hint 2
+
+ Instead of calculating the sum for every subarray, try maintaining a running sum. Maybe you should consider whether extending the previous sum or starting fresh with the current element gives a better result. Can you think of a way to track this efficiently?
+
+
+
+
+
+ Hint 3
+
+ We use a variable curSum
to track the sum of the elements. At each index, we have two choices: either add the current element to curSum
or start a new subarray by resetting curSum
to the current element. Maybe you should track the maximum sum at each step and update the global maximum accordingly.
+
+
+
+
+
+ Hint 4
+
+ This algorithm is known as Kadane's algorithm.
+
+
\ No newline at end of file
diff --git a/hints/meeting-schedule-ii.md b/hints/meeting-schedule-ii.md
new file mode 100644
index 000000000..1342e260f
--- /dev/null
+++ b/hints/meeting-schedule-ii.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(nlogn)
time and O(n)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ Try to visualize the meetings as line segments on a number line representing start and end times. The number of rooms required is the maximum number of overlapping meetings at any point on the number line. Can you think of a way to determine this efficiently?
+
+
+
+
+
+ Hint 2
+
+ We create two arrays, start and end, containing the start and end times of all meetings, respectively. After sorting both arrays, we use a two-pointer based approach. How do you implement this?
+
+
+
+
+
+ Hint 3
+
+ We use two pointers, s
and e
, for the start and end arrays, respectively. We also maintain a variable count
to track the current number of active meetings. At each iteration, we increment s
while the start time is less than the current end time and increase count
, as these meetings must begin before the earliest ongoing meeting ends.
+
+
+
+
+
+ Hint 4
+
+ Then, we increment e
and decrement count
as a meeting has ended. At each step, we update the result with the maximum value of active meetings stored in count
.
+
+
\ No newline at end of file
diff --git a/hints/meeting-schedule.md b/hints/meeting-schedule.md
new file mode 100644
index 000000000..0216b7b66
--- /dev/null
+++ b/hints/meeting-schedule.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(nlogn)
time and O(n)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ If two intervals are sorted in ascending order by their start values, they overlap if the start value of the second interval is less than the end value of the first interval. And these are called overlapping intervals.
+
+
+
+
+
+ Hint 2
+
+ A brute force approach would be to check every pair of intervals and return false
if any overlap is found. This would be an O(n^2)
solution. Can you think of a better way? Maybe you should visualize the given intervals as line segments.
+
+
+
+
+
+ Hint 3
+
+ We should sort the given intervals based on their start values, as this makes it easier to check for overlaps by comparing adjacent intervals. We then iterate through the intervals from left to right and return false
if any adjacent intervals overlap.
+
+
\ No newline at end of file
diff --git a/hints/merge-intervals.md b/hints/merge-intervals.md
new file mode 100644
index 000000000..89af36fe5
--- /dev/null
+++ b/hints/merge-intervals.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(nlogn)
time and O(n)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ Sorting the given intervals in ascending order based on their start values is beneficial, as it helps in identifying overlapping intervals efficiently. How can you determine if two intervals overlap?
+
+
+
+
+
+ Hint 2
+
+ If two intervals are sorted in ascending order by their start values, they overlap if the start value of the second interval is less than or equal to the end value of the first interval.
+
+
+
+
+
+ Hint 3
+
+ We iterate through the sorted intervals from left to right, starting with the first interval in the output list. From the second interval onward, we compare each interval with the last appended interval. Can you determine the possible cases for this comparison?
+
+
+
+
+
+ Hint 4
+
+ The two cases are: if the current interval overlaps with the last appended interval, we update its end value to the maximum of both intervals' end values and continue. Otherwise, we append the current interval and proceed.
+
+
\ No newline at end of file
diff --git a/hints/merge-triplets-to-form-target.md b/hints/merge-triplets-to-form-target.md
new file mode 100644
index 000000000..fd475aa48
--- /dev/null
+++ b/hints/merge-triplets-to-form-target.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(n)
time and O(1)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ An important observation is that we can ignore triplets with values greater than the target triplet.
+
+
+
+
+
+ Hint 2
+
+ Specifically, if a triplet t
has any element greater than the corresponding value in target
(i.e., t[0] > target[0]
, t[1] > target[1]
, or t[2] > target[2]
), we can discard it. This is because using such a triplet in operations would exceed the target values, making it invalid.
+
+
+
+
+
+ Hint 3
+
+ Now, from the remaining valid triplets, we only need to check whether the target triplet values exist. Since all values in the valid triplets are less than or equal to the corresponding values in the target triplet, finding the target triplet among them guarantees that we can achieve it.
+
+
\ No newline at end of file
diff --git a/hints/minimum-interval-including-query.md b/hints/minimum-interval-including-query.md
new file mode 100644
index 000000000..9b56faba2
--- /dev/null
+++ b/hints/minimum-interval-including-query.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(nlogn + mlogm)
time and O(n + m)
space, where m
is the size of the array queries
and n
is the size of the array intervals
.
+
+
+
+
+
+ Hint 1
+
+ A brute force approach would be to iterate through each query and, for each query, check all intervals to find the result. This would be an O(m * n)
solution. Can you think of a better way? Maybe processing the queries in sorted order could help.
+
+
+
+
+
+ Hint 2
+
+ We sort the intervals by start value and process the queries in ascending order. Using a pointer i
, we add intervals to a min-heap while their start values are less than or equal to the query, storing their end values and sizes.
+
+
+
+
+
+ Hint 3
+
+ The min-heap is ordered by interval size. We remove elements from the heap while the top element’s end value is less than the current query. The result for the query is the top element’s size if the heap is non-empty; otherwise, it is -1
.
+
+
\ No newline at end of file
diff --git a/hints/missing-number.md b/hints/missing-number.md
new file mode 100644
index 000000000..2d5f6908b
--- /dev/null
+++ b/hints/missing-number.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(n)
time and O(1)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ A brute force approach would iterate through the range of numbers from 0
to n
, checking if each number is present in the given array. If a number is missing, it is returned. This results in an O(n^2)
solution. Can you think of a better way? Maybe a data structure could help optimize this process.
+
+
+
+
+
+ Hint 2
+
+ We can use a hash set by inserting the given array elements into it. Then, we iterate through the range of numbers from 0
to n
and use the hash set for O(1)
lookups to find the missing number. Can you think of a way to further optimize this? Maybe a bitwise operator could be useful.
+
+
+
+
+
+ Hint 3
+
+ We can use bitwise XOR. When two identical numbers are XORed, the result is 0
. Using this property, we can efficiently find the missing number.
+
+
+
+
+
+ Hint 4
+
+ We first compute the bitwise XOR of numbers from 0
to n
. Then, we iterate through the array and XOR its elements as well. The missing number remains in the final XOR result since all other numbers appear twice—once in the range and once in the array—while the missing number is XORed only once.
+
+
\ No newline at end of file
diff --git a/hints/multiply-strings.md b/hints/multiply-strings.md
new file mode 100644
index 000000000..193cc4c27
--- /dev/null
+++ b/hints/multiply-strings.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(m*n)
time and O(m+n)
space, where m
is the length of the string num1
and n
is the length of the string num2
.
+
+
+
+
+
+ Hint 1
+
+ Implement a helper function that takes two number strings and returns their sum. Ensure that the length of num1
is greater than num2
, swapping them if necessary. Can you think of a way to multiply the strings? Maybe you should first consider basic multiplication, where num1
is multiplied by each digit of num2
.
+
+
+
+
+
+ Hint 2
+
+ When multiplying num1
with each digit of num2
, we iterate through num2
in reverse order. Based on the digit's position, we pad zeros to the multiplication result accordingly—no padding for the last digit, one zero for the second last, and so on. What should be the next step after each multiplication? Maybe you should implement a helper function to handle this.
+
+
+
+
+
+ Hint 3
+
+ We implement a helper function that takes num1
, a digit, and a variable zeroes
, returning the multiplication result with zeroes
padded at the end. A global string res
stores the final result.
+
+
+
+
+
+ Hint 4
+
+ In the main function, we iterate through num2
in reverse order, calling the helper function to multiply num1
with the current digit and append the appropriate number of padding zeros. We then call another helper function that takes this multiplication result and the global result string res
, adds them, and updates res
.
+
+
\ No newline at end of file
diff --git a/hints/non-cyclical-number.md b/hints/non-cyclical-number.md
new file mode 100644
index 000000000..6672425b9
--- /dev/null
+++ b/hints/non-cyclical-number.md
@@ -0,0 +1,23 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(logn)
time and O(logn)
space, where n
is the given integer.
+
+
+
+
+
+ Hint 1
+
+ Create a helper function that returns the sum of the squares of a number's digits. Then, simulate the given process. If we reach 1
, return true
. However, we may get stuck in a cycle if a number is processed more than once. What data structure can be used to detect if a number has already been processed?
+
+
+
+
+
+ Hint 2
+
+ We can use a hash set to detect if a number has already been processed. At each step, we update n
with the return value of the helper function. If the result is 1
, we return true
. If n
is already in the set, we return false
. Otherwise, we add n
to the hash set and continue.
+
+
\ No newline at end of file
diff --git a/hints/non-overlapping-intervals.md b/hints/non-overlapping-intervals.md
new file mode 100644
index 000000000..1e07a9c0b
--- /dev/null
+++ b/hints/non-overlapping-intervals.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(nlogn)
time and O(n)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ If two intervals are sorted in ascending order by their start values, they overlap if the start value of the second interval is less than the end value of the first interval. And these are called overlapping intervals.
+
+
+
+
+
+ Hint 2
+
+ A brute force approach would be to sort the given intervals in ascending order based on their start values and recursively explore all possibilities. This would be an exponential approach. Can you think of a better way? Maybe a greedy approach works here.
+
+
+
+
+
+ Hint 3
+
+ We first sort the given intervals based on their start values to efficiently check for overlaps by comparing adjacent intervals. We then iterate through the sorted intervals from left to right, keeping track of the previous interval’s end value as prevEnd
, initially set to the end value of the first interval.
+
+
+
+
+
+ Hint 4
+
+ We then iterate from the second interval. If the current interval doesn't overlap, we update prevEnd
to the current interval's end and continue. Otherwise, we set prevEnd
to the minimum of prevEnd
and the current interval’s end, greedily removing the interval that ends last to retain as many intervals as possible.
+
+
\ No newline at end of file
diff --git a/hints/number-of-one-bits.md b/hints/number-of-one-bits.md
new file mode 100644
index 000000000..788499e2b
--- /dev/null
+++ b/hints/number-of-one-bits.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(1)
time and O(1)
space.
+
+
+
+
+
+ Hint 1
+
+ The given integer is a 32
-bit integer. Can you think of using bitwise operators to iterate through its bits? Maybe you should consider iterating 32
times.
+
+
+
+
+
+ Hint 2
+
+ We iterate 32
times (0 to 31)
using index i
. The expression (1 << i)
creates a bitmask with a set bit at the i
-th position. How can you check whether the i
-th bit is set in the given number? Maybe you should consider using the bitwise-AND ("&")
.
+
+
+
+
+
+ Hint 3
+
+ Since the mask has a set bit at the i
-th position and all 0
s elsewhere, we can perform a bitwise-AND with n
. If n
has a set bit at the i
-th position, the result is positive; otherwise, it is 0
. We increment the global count if the result is positive and return it after the iteration.
+
+
\ No newline at end of file
diff --git a/hints/partition-equal-subset-sum.md b/hints/partition-equal-subset-sum.md
new file mode 100644
index 000000000..6dfc98881
--- /dev/null
+++ b/hints/partition-equal-subset-sum.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(n * t)
time and O(n * t)
space, where n
is the size of the input array and t
is half the sum of the array elements.
+
+
+
+
+
+ Hint 1
+
+ If the sum of the array elements is not even, we can immediately return false
. Think in terms of recursion, where we try to build a subset with a sum equal to half of the total sum. If we find such a subset, the remaining elements will automatically form another subset with the same sum. The entire array can also be considered as one subset, with the other being empty. Can you visualize this as a decision tree to process the array recursively?
+
+
+
+
+
+ Hint 2
+
+ We recursively iterate through the array with index i
. At each step, we decide whether to include the current element in the subset or not. Instead of forming the subset explicitly, can you think of a better approach? Maybe you only need to track the subset sum rather than generating the subset itself.
+
+
+
+
+
+ Hint 3
+
+ We can track the subset sum using a variable curSum
. At each step, we make two recursive calls. If adding the current element does not exceed the target, we include it. If either path leads to a solution, we immediately return true
. Can you determine the base case for this recursion? All elements in the array are positive.
+
+
+
+
+
+ Hint 4
+
+ If curSum
equals half the sum of the array elements, we return true
. If index i
goes out of bounds, we return false
. This solution is exponential, but we can use memoization to cache recursive call results and avoid redundant computations. We can use a hash map or a 2D
array with dimensions n * t
, where n
is the size of the input array and t
is half the sum of the input array elements.
+
+
\ No newline at end of file
diff --git a/hints/partition-labels.md b/hints/partition-labels.md
new file mode 100644
index 000000000..c5e3551bb
--- /dev/null
+++ b/hints/partition-labels.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(n)
time and O(m)
space, where n
is the length of the string s
and m
is the number of unique characters in the string s
.
+
+
+
+
+
+ Hint 1
+
+ A character has a first and last index in the given string. Can you think of a greedy approach to solve this problem? Maybe you should try iterating over one of these two indices.
+
+
+
+
+
+ Hint 2
+
+ We store the last index of each character in a hash map or an array. As we iterate through the string, treating each index as a potential start of a partition, we track the end of the partition using the maximum last index of the characters seen so far in the current partition. Additionally, we maintain the size of the current partition using a variable, say size
.
+
+
+
+
+
+ Hint 3
+
+ We update the end of the current partition based on the maximum last index of the characters, extending the partition as needed. When the current index reaches the partition’s end, we finalize the partition, append its size to the output list, reset the size to 0
, and continue the same process for the remaining string.
+
+
\ No newline at end of file
diff --git a/hints/plus-one.md b/hints/plus-one.md
new file mode 100644
index 000000000..ec62b78c9
--- /dev/null
+++ b/hints/plus-one.md
@@ -0,0 +1,23 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(n)
time and O(n)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ There are two cases when adding 1
to a number. If the rightmost digit is less than 9
, we simply increment it. Otherwise, we set it to 0
and apply the same process to the preceding digit.
+
+
+
+
+
+ Hint 2
+
+ We iterate through the given digits
from right to left using index i
. If the current digit is less than 9
, we increment it and return the array. Otherwise, we set the digit to 0
and continue. If the loop completes without returning, we insert 1
at the beginning of the array and return it.
+
+
\ No newline at end of file
diff --git a/hints/pow-x-n.md b/hints/pow-x-n.md
new file mode 100644
index 000000000..de42350f0
--- /dev/null
+++ b/hints/pow-x-n.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(logn)
time and O(logn)
space, where n
is the given integer.
+
+
+
+
+
+ Hint 1
+
+ A brute force approach would be to iterate linearly up to n
, multiplying by x
each time to find (x^n)
. If n
is negative, return (1 / (x^n))
; otherwise, return (x^n)
. Can you think of a better way? Maybe a recursive approach would be more efficient.
+
+
+
+
+
+ Hint 2
+
+ For example, to calculate 2^6
, instead of multiplying 2
six times, we compute 2^3
and square the result. The same logic applies recursively to find 2^3
and further break down the multiplication. What should be the base case for this recursion? Maybe you should consider the term that cannot be further broken down.
+
+
+
+
+
+ Hint 3
+
+ In (x^n)
, if x
is 0
, we return 0
. If n
is 0
, we return 1
, as any number raised to the power of 0
is 1
. Otherwise, we compute (x^(n/2))
recursively and square the result. If n
is odd, we multiply the final result by x
. What should be the logic if n
is negative?
+
+
+
+
+
+ Hint 4
+
+ We start the recursion with the absolute value of n
. After computing the result as res
, we return res
if n
is non-negative; otherwise, we return (1 / res)
.
+
+
\ No newline at end of file
diff --git a/hints/regular-expression-matching.md b/hints/regular-expression-matching.md
new file mode 100644
index 000000000..e17c78964
--- /dev/null
+++ b/hints/regular-expression-matching.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(m * n)
time and O(m * n)
space, where m
is the length of the string s
and n
is the length of the string p
.
+
+
+
+
+
+ Hint 1
+
+ Try to think in terms of recursion and visualize it as a decision tree, where we explore different combinations to match the strings when encountering *
. Multiple decisions are made at each step to find a valid matching path. Can you determine the possible decisions at each recursion step?
+
+
+
+
+
+ Hint 2
+
+ We recursively iterate through the strings using indices i
and j
for s
and p
, respectively. If the characters match or p[j]
is '.'
, we increment both i
and j
to process the remaining strings. When the next character of string p
is '*'
, we have two choices: skip it (treating it as zero occurrences) or match one or more characters (if s[i]
matches p[j]
), incrementing i
accordingly.
+
+
+
+
+
+ Hint 3
+
+ If both indices go out of bounds, we return true
; otherwise, we return false
. If any recursive path returns true
, we immediately return true
. This approach is exponential. Can you think of a way to optimize it?
+
+
+
+
+
+ Hint 4
+
+ We can use memoization to cache the results of recursive calls and avoid redundant calculations. A hash map or a 2D
array can be used to store these results.
+
+
\ No newline at end of file
diff --git a/hints/reverse-bits.md b/hints/reverse-bits.md
new file mode 100644
index 000000000..0eb364ce9
--- /dev/null
+++ b/hints/reverse-bits.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(1)
time and O(1)
space.
+
+
+
+
+
+ Hint 1
+
+ Given a 32-bit integer, what is the position of bit i
after reversing the bits? Maybe you should observe the bit positions before and after reversal to find a pattern.
+
+
+
+
+
+ Hint 2
+
+ After reversing the bits, the bit at position i
moves to position 31 - i
. Can you use this observation to construct the reversed number efficiently?
+
+
+
+
+
+ Hint 3
+
+ We initialize res
to 0
and iterate through the bits of the given integer n
. We extract the bit at the i
-th position using ((n >> i) & 1)
. If it is 1
, we set the corresponding bit in res
at position (31 - i)
using (res |= (1 << (31 - i)))
.
+
+
\ No newline at end of file
diff --git a/hints/reverse-integer.md b/hints/reverse-integer.md
new file mode 100644
index 000000000..23b4d9c75
--- /dev/null
+++ b/hints/reverse-integer.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(1)
time and O(1)
space.
+
+
+
+
+
+ Hint 1
+
+ A straightforward approach would be to convert the given integer to a string, reverse it, convert it back to an integer using a long type, and return 0 if the result exceeds the integer range. Can you think of a better way?
+
+
+
+
+
+ Hint 2
+
+ We initially declare the result res
as an int
with a value of 0
. We iterate through the given integer, extracting digits one by one. Before appending a digit to res
, we consider multiple cases. Can you determine them? Maybe you should think about overflow.
+
+
+
+
+
+ Hint 3
+
+ Let MAX
be the maximum positive integer and MIN
be the minimum negative integer. We iterate through each digit and check for overflow before updating res
. If res > MAX / 10
or res < MIN / 10
, return 0
. If res == MAX / 10
and the current digit is greater than MAX % 10
, return 0
. If res == MIN / 10
and the current digit is less than MIN % 10
, return 0
. Otherwise, append the digit to res
and continue.
+
+
\ No newline at end of file
diff --git a/hints/rotate-matrix.md b/hints/rotate-matrix.md
new file mode 100644
index 000000000..3f5528d0f
--- /dev/null
+++ b/hints/rotate-matrix.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(n^2)
time and O(1)
space, where n
is the length of the side of the given square matrix.
+
+
+
+
+
+ Hint 1
+
+ A brute force approach would use O(n^2)
extra space to solve the problem. Can you think of a way to avoid using extra space? Maybe you should consider observing the positions of the elements before rotating and after rotating of the matrix.
+
+
+
+
+
+ Hint 2
+
+ We can rotate the matrix in two steps. First, we reverse the matrix vertically, meaning the first row becomes the last, the second row becomes the second last, and so on. Next, we transpose the reversed matrix, meaning rows become columns and columns become rows. How would you transpose the matrix?
+
+
+
+
+
+ Hint 3
+
+ Since the given matrix is a square matrix, we only need to iterate over the upper triangular part, meaning the right upper portion of the main diagonal. In this way, we can transpose a matrix.
+
+
\ No newline at end of file
diff --git a/hints/set-zeroes-in-matrix.md b/hints/set-zeroes-in-matrix.md
new file mode 100644
index 000000000..663ff919e
--- /dev/null
+++ b/hints/set-zeroes-in-matrix.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(m*n)
time and O(1)
space, where m
is the number of rows and n
is the number of columns in the given matrix.
+
+
+
+
+
+ Hint 1
+
+ A brute force approach would iterate through the given matrix and update the corresponding row and column in a new matrix on the fly. This would result in an O((m*n)*(m+n))
time and O(m*n)
space solution. Can you think of a better way? Maybe you should consider using a single variable for a row and a single variable for a column instead of updating entire row and column.
+
+
+
+
+
+ Hint 2
+
+ A better approach is to use O(m+n)
boolean arrays. We iterate through the matrix, and when encountering a zero, we mark the respective row and column as true
. In the second iteration, we set a cell to 0
if its corresponding row or column is marked true
. Can you think of a way to optimize the space further?
+
+
+
+
+
+ Hint 3
+
+ We can use the topmost row and leftmost column of the matrix as boolean arrays by marking 0
instead of true
. However, since they overlap at one cell, we use a single variable to track the top row separately. We then iterate through the matrix and mark zeros accordingly.
+
+
+
+
+
+ Hint 4
+
+ In the second iteration, we update all cells that are not part of the top row or left column accordingly. After making the necessary changes, we check the top-leftmost cell and update the corresponding column. Finally, we check the extra variable and update the top row accordingly.
+
+
\ No newline at end of file
diff --git a/hints/single-number.md b/hints/single-number.md
new file mode 100644
index 000000000..6aab0485f
--- /dev/null
+++ b/hints/single-number.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(n)
time and O(1)
space, where n
is the size of the input array.
+
+
+
+
+
+ Hint 1
+
+ A brute force approach would iterate through the array, checking each element using a nested loop. If a duplicate is found, we continue to the next element; otherwise, the current element is the required number. This results in an O(n^2)
solution. Can you think of a better way? Maybe a data structure can help detect duplicates efficiently.
+
+
+
+
+
+ Hint 2
+
+ We use a hash set, iterating through the array and adding elements that are not in the set while removing those that are already present. After the iteration, the required number remains in the hash set. This results in an O(n)
space solution. Can you further optimize it? Maybe a bitwise operator could be useful here.
+
+
+
+
+
+ Hint 3
+
+ Think about the bitwise XOR ("^")
. What is the result when two identical numbers are XORed?
+
+
+
+
+
+ Hint 4
+
+ When two identical numbers are XORed, they cancel out, resulting in zero. Since every number appears twice except for one, the XOR of the entire array gives the number that appears only once.
+
+
\ No newline at end of file
diff --git a/hints/spiral-matrix.md b/hints/spiral-matrix.md
new file mode 100644
index 000000000..2b8eced0a
--- /dev/null
+++ b/hints/spiral-matrix.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(m*n)
time and O(1)
extra space, where m
is the number of rows and n
is the number of columns in the given matrix.
+
+
+
+
+
+ Hint 1
+
+ Try to simulate the process as described in the problem. Think in terms of matrix layers, starting from the outermost boundaries and moving inward. Can you determine an efficient way to implement this?
+
+
+
+
+
+ Hint 2
+
+ Each boundary consists of four parts: the top row, right column, bottom row, and left column, which follow the spiral order and act as four pointers. For each layer, the top pointer increments by one, the right pointer decrements by one, the left pointer increments by one, and the bottom pointer decrements by one.
+
+
+
+
+
+ Hint 3
+
+ At each layer, four loops traverse the matrix: one moves left to right along the top row, another moves top to bottom along the right column, the next moves right to left along the bottom row, and the last moves bottom to top along the left column. This process generates the spiral order.
+
+
\ No newline at end of file
diff --git a/hints/string-encode-and-decode.md b/hints/string-encode-and-decode.md
index 39083d5be..82bc8fbcb 100644
--- a/hints/string-encode-and-decode.md
+++ b/hints/string-encode-and-decode.md
@@ -2,7 +2,7 @@
Recommended Time & Space Complexity
- You should aim for a solution with O(m)
time and O(1)
space for each encode()
and decode()
call, where m
is the sum of lengths of all the strings.
+ You should aim for a solution with O(m)
time for each encode()
and decode()
call and O(m+n)
space, where m
is the sum of lengths of all the strings and n
is the number of strings.
diff --git a/hints/sum-of-two-integers.md b/hints/sum-of-two-integers.md
new file mode 100644
index 000000000..340f197d0
--- /dev/null
+++ b/hints/sum-of-two-integers.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution with O(1)
time and O(1)
space.
+
+
+
+
+
+ Hint 1
+
+ A brute force approach would use the addition operator. Can you think of a way to perform addition without using it? Maybe you should consider solving this using bit manipulation.
+
+
+
+
+
+ Hint 2
+
+ We can use the bitwise XOR operator to perform addition. If both a
and b
have 1
at the same bit position, the sum at that position is 0
, and a carry of 1
is generated. If the bits are different, the sum at that position is 1
. Additionally, we account for the carry from the previous step in the next iteration.
+
+
+
+
+
+ Hint 3
+
+ We iterate bit by bit from 0
to 31
since the given integers are 32-bit. We track the carry, initially set to 0
, and initialize the result as res
. During iteration, the XOR of the bits at the i
-th position of both integers and the carry determines the current bit of res
. How can you handle negative numbers?
+
+
+
+
+
+ Hint 4
+
+ To handle negative numbers, if the final result exceeds the maximum positive 32-bit integer, it means the number should be negative. We adjust it using bitwise operations: flipping the bits with res ^ ((2 ^ 32) - 1)
and applying ~
to restore the correct two’s complement representation. This ensures the result correctly represents signed 32-bit integers.
+
+
\ No newline at end of file
diff --git a/hints/target-sum.md b/hints/target-sum.md
new file mode 100644
index 000000000..06e9e9a3e
--- /dev/null
+++ b/hints/target-sum.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(n * m)
time and O(n * m)
space, where n
is the size of the input array and m
is the sum of all the elements in the array.
+
+
+
+
+
+ Hint 1
+
+ Try to think in terms of recursion and visualize it as a decision tree, where we have two choices at each recursion step: assigning a positive or negative sign.
+
+
+
+
+
+ Hint 2
+
+ We recursively iterate through the array using index i
, tracking the current sum along the recursive path. Each step branches into two paths, and we sum the number of ways to reach the target. If the index i
goes out of bounds, we return 1
if the current sum equals the target; otherwise, we return 0
.
+
+
+
+
+
+ Hint 3
+
+ This approach is exponential. We can use memoization to cache recursive call results and avoid redundant calculations. A hash map or a 2D
array with modifications can be used for caching. If using a 2D
array, the dimensions can be (n * (2m + 1))
, where n
is the array size and m
represents the sum of the array elements.
+
+
\ No newline at end of file
diff --git a/hints/valid-parenthesis-string.md b/hints/valid-parenthesis-string.md
new file mode 100644
index 000000000..29baed7d5
--- /dev/null
+++ b/hints/valid-parenthesis-string.md
@@ -0,0 +1,39 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(n)
time and O(n)
space, where n
is the length of the input string.
+
+
+
+
+
+ Hint 1
+
+ A brute force approach would try all possibilities when encountering a '*'
and recursively solve the problem, leading to an exponential approach. Can you think of a better way? Maybe a data structure commonly used in parenthesis problems could be useful.
+
+
+
+
+
+ Hint 2
+
+ We can solve the problem using a stack-based approach. We maintain two stacks: one for tracking the indices of left parentheses and another for star indices. As we iterate through the string from left to right, we push indices onto their respective stacks when encountering a left parenthesis '('
or a star '*'
. Can you determine the logic for the right parentesis case?
+
+
+
+
+
+ Hint 3
+
+ If the left parenthesis stack is not empty, we pop from it. Otherwise, we pop from the star stack, treating the star as a left parenthesis to keep the string valid. After iterating the string, the stacks might be non-empty? Can you determine the logic for this case?
+
+
+
+
+
+ Hint 4
+
+ Now, we try to match the remaining left parentheses with stars, ensuring the stars appear after the left parentheses in the string. We simultaneously pop from both stacks, and if the index of a left parenthesis is greater than that of a star, the string is invalid as there is no matching right parenthesis. In this case, we return false
.
+
+
\ No newline at end of file
diff --git a/hints/word-break.md b/hints/word-break.md
new file mode 100644
index 000000000..cb850a49c
--- /dev/null
+++ b/hints/word-break.md
@@ -0,0 +1,31 @@
+
+
+ Recommended Time & Space Complexity
+
+ You should aim for a solution as good or better than O(n * m * t)
time and O(n)
space, where n
is the length of the string s
, m
is the number of words in wordDict
, and t
is the maximum length of any word in wordDict
.
+
+
+
+
+
+ Hint 1
+
+ Try to think of this problem in terms of recursion, where we explore all possibilities. We iterate through the given string s
, attempting to pick a word from wordDict
that matches a portion of s
, and then recursively continue processing the remaining string. Can you determine the recurrence relation and base condition?
+
+
+
+
+
+ Hint 2
+
+ The base condition is to return true
if we reach the end of the string s
. At each recursive call with index i
iterating through s
, we check all words in wordDict
and recursively process the remaining string by incrementing i
by the length of the matched word. If any recursive path returns true
, we immediately return true
. However, this solution is exponential. Can you think of an optimization? Maybe you should consider an approach that avoids repeated work.
+
+
+
+
+
+ Hint 3
+
+ We can avoid recalculating results for recursive calls by using memoization. Since we iterate with index i
, we can use a hash map or an array of the same length as s
to cache the results of recursive calls and prevent redundant computations.
+
+
\ No newline at end of file
From 0a2d881f8e72fa645203cddf31c3ea7f43a35812 Mon Sep 17 00:00:00 2001
From: Sri Hari <94112314+Srihari2222@users.noreply.github.com>
Date: Mon, 24 Mar 2025 02:44:23 +0530
Subject: [PATCH 2/9] Sri Hari: Batch-6/Neetcode-150/Added-SwiftCode (#3936)
* Batch-6/Neetcode-150/Added-swiftcode
* Batch-6/Neetcode-150/Added-swiftcode
* Batch-6/Neetcode-150/Added-swiftcode
* Batch-6/Neetcode-150/Added-swiftcode
* Batch-6/Neetcode-150/Added-swiftcode
* Batch-6/Neetcode-150/Added-swiftcode
* Batch-6/Neetcode-150/Added-swiftcode
* Batch-6/Neetcode-150/Added-swiftcode
* Batch-6/Neetcode-150/Added-swiftcode
* Batch-6/Neetcode-150/Added-swiftcode
* Batch-6/Neetcode-150/Added-swiftcode
* Batch-6/Neetcode-150/Added-swiftcode
* Batch-6/Neetcode-150/Added-swiftcode
---
articles/add-two-numbers.md | 74 +-
articles/anagram-groups.md | 39 +-
articles/balanced-binary-tree.md | 124 +++-
articles/binary-search.md | 90 +++
articles/binary-tree-diameter.md | 112 +++
...ree-from-preorder-and-inorder-traversal.md | 130 ++++
articles/binary-tree-maximum-path-sum.md | 79 +++
articles/binary-tree-right-side-view.md | 78 +++
articles/burst-balloons.md | 75 ++
articles/buy-and-sell-crypto-with-cooldown.md | 100 +++
articles/buy-and-sell-crypto.md | 51 ++
articles/car-fleet.md | 44 ++
articles/cheapest-flight-path.md | 107 +++
articles/climbing-stairs.md | 120 ++++
articles/clone-graph.md | 84 +++
articles/coin-change-ii.md | 157 ++++-
articles/coin-change.md | 111 +++
articles/combination-target-sum-ii.md | 136 ++++
articles/combination-target-sum.md | 56 ++
articles/combinations-of-a-phone-number.md | 67 +-
.../copy-linked-list-with-random-pointer.md | 231 ++++++-
articles/count-connected-components.md | 124 +++-
articles/count-good-nodes-in-binary-tree.md | 78 +++
articles/count-number-of-islands.md | 149 +++-
articles/count-paths.md | 117 ++++
articles/count-squares.md | 73 +-
articles/count-subsequences.md | 161 ++++-
articles/counting-bits.md | 75 ++
articles/course-schedule-ii.md | 121 ++++
articles/course-schedule.md | 82 +++
articles/daily-temperatures.md | 75 +-
articles/decode-ways.md | 105 +++
articles/depth-of-binary-tree.md | 100 +++
articles/design-twitter-feed.md | 229 ++++++
articles/design-word-search-data-structure.md | 94 +++
articles/duplicate-integer.md | 54 +-
articles/eating-bananas.md | 47 ++
articles/edit-distance.md | 141 ++++
articles/evaluate-reverse-polish-notation.md | 147 ++++
articles/find-duplicate-integer.md | 137 ++++
articles/find-median-in-a-data-stream.md | 65 ++
.../find-minimum-in-rotated-sorted-array.md | 51 ++
.../find-target-in-rotated-sorted-array.md | 124 ++++
articles/foreign-dictionary.md | 122 ++++
articles/gas-station.md | 93 +++
articles/generate-parentheses.md | 85 +++
articles/hand-of-straights.md | 147 ++++
articles/house-robber-ii.md | 110 +++
articles/house-robber.md | 75 ++
articles/implement-prefix-tree.md | 109 +++
articles/insert-new-interval.md | 91 +++
articles/interleaving-string.md | 157 +++++
articles/invert-a-binary-tree.md | 212 +++++-
articles/is-anagram.md | 63 +-
articles/is-palindrome.md | 44 ++
articles/islands-and-treasure.md | 132 ++++
articles/jump-game-ii.md | 103 ++-
articles/jump-game.md | 93 +++
articles/k-closest-points-to-origin.md | 121 +++-
articles/kth-largest-element-in-an-array.md | 122 ++++
articles/kth-largest-integer-in-a-stream.md | 48 +-
articles/kth-smallest-integer-in-bst.md | 197 ++++++
articles/largest-rectangle-in-histogram.md | 198 +++++-
articles/last-stone-weight.md | 108 +++
.../level-order-traversal-of-binary-tree.md | 84 ++-
articles/linked-list-cycle-detection.md | 61 ++
articles/longest-common-subsequence.md | 134 ++++
articles/longest-consecutive-sequence.md | 103 ++-
articles/longest-increasing-path-in-matrix.md | 114 +++
articles/longest-increasing-subsequence.md | 651 +++++++++++++++++-
articles/longest-palindromic-substring.md | 138 +++-
...st-repeating-substring-with-replacement.md | 78 +++
.../longest-substring-without-duplicates.md | 60 ++
...t-common-ancestor-in-binary-search-tree.md | 67 ++
articles/lru-cache.md | 149 ++++
articles/max-area-of-island.md | 148 +++-
articles/max-water-container.md | 34 +
articles/maximum-product-subarray.md | 106 +++
articles/maximum-subarray.md | 150 ++++
articles/median-of-two-sorted-arrays.md | 123 +++-
articles/meeting-schedule-ii.md | 134 ++++
articles/meeting-schedule.md | 56 ++
articles/merge-intervals.md | 92 +++
articles/merge-k-sorted-linked-lists.md | 336 +++++++++
articles/merge-triplets-to-form-target.md | 43 ++
articles/merge-two-sorted-linked-lists.md | 66 ++
articles/min-cost-climbing-stairs.md | 63 ++
articles/min-cost-to-connect-points.md | 156 ++++-
articles/minimum-interval-including-query.md | 252 ++++++-
articles/minimum-stack.md | 142 +++-
articles/minimum-window-with-characters.md | 89 +++
articles/missing-number.md | 59 ++
articles/multiply-strings.md | 97 +++
articles/n-queens.md | 175 +++++
articles/network-delay-time.md | 174 +++++
articles/non-cyclical-number.md | 92 +++
articles/non-overlapping-intervals.md | 155 +++++
articles/number-of-one-bits.md | 50 ++
articles/pacific-atlantic-water-flow.md | 149 ++++
articles/palindrome-partitioning.md | 177 ++++-
articles/palindromic-substrings.md | 139 ++++
articles/partition-equal-subset-sum.md | 171 ++++-
articles/partition-labels.md | 25 +
articles/permutation-string.md | 109 ++-
articles/permutations.md | 124 ++++
articles/plus-one.md | 66 ++
articles/pow-x-n.md | 69 +-
articles/products-of-array-discluding-self.md | 117 +++-
articles/reconstruct-flight-path.md | 89 +++
articles/redundant-connection.md | 185 +++++
articles/regular-expression-matching.md | 158 +++++
.../remove-node-from-end-of-linked-list.md | 138 +++-
articles/reorder-linked-list.md | 152 +++-
articles/reverse-a-linked-list.md | 56 ++
articles/reverse-bits.md | 52 ++
articles/reverse-integer.md | 68 ++
articles/reverse-nodes-in-k-group.md | 92 +++
articles/rotate-matrix.md | 69 ++
articles/rotting-fruit.md | 106 +++
articles/same-binary-tree.md | 114 +++
articles/search-2d-matrix.md | 99 +++
articles/search-for-word-ii.md | 192 +++++-
articles/search-for-word.md | 115 ++++
.../serialize-and-deserialize-binary-tree.md | 125 ++++
articles/set-zeroes-in-matrix.md | 100 +++
articles/single-number.md | 69 ++
articles/sliding-window-maximum.md | 179 ++++-
articles/spiral-matrix.md | 90 +++
articles/string-encode-and-decode.md | 85 +++
articles/subsets-ii.md | 131 +++-
articles/subsets.md | 71 +-
articles/subtree-of-a-binary-tree.md | 121 +++-
articles/sum-of-two-integers.md | 53 ++
articles/surrounded-regions.md | 176 ++++-
articles/swim-in-rising-water.md | 239 ++++++-
articles/target-sum.md | 73 ++
articles/task-scheduling.md | 120 ++++
articles/three-integer-sum.md | 100 ++-
articles/time-based-key-value-store.md | 110 +++
articles/top-k-elements-in-list.md | 90 ++-
articles/trapping-rain-water.md | 111 +++
articles/two-integer-sum-ii.md | 77 +++
articles/two-integer-sum.md | 82 +++
articles/valid-binary-search-tree.md | 111 +++
articles/valid-parenthesis-string.md | 215 ++++++
articles/valid-sudoku.md | 98 +++
articles/valid-tree.md | 138 +++-
articles/validate-parentheses.md | 37 +
articles/word-break.md | 209 +++++-
articles/word-ladder.md | 231 +++++++
150 files changed, 17199 insertions(+), 148 deletions(-)
diff --git a/articles/add-two-numbers.md b/articles/add-two-numbers.md
index 6225ac227..118adab49 100644
--- a/articles/add-two-numbers.md
+++ b/articles/add-two-numbers.md
@@ -303,6 +303,40 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ private func add(_ l1: ListNode?, _ l2: ListNode?, _ carry: Int) -> ListNode? {
+ if l1 == nil && l2 == nil && carry == 0 {
+ return nil
+ }
+
+ let v1 = l1?.val ?? 0
+ let v2 = l2?.val ?? 0
+
+ let sum = v1 + v2 + carry
+ let newCarry = sum / 10
+ let val = sum % 10
+
+ let nextNode = add(l1?.next, l2?.next, newCarry)
+ return ListNode(val, nextNode)
+ }
+
+ func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
+ return add(l1, l2, 0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -577,11 +611,49 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
+ let dummy = ListNode(0)
+ var cur = dummy
+ var l1 = l1, l2 = l2
+ var carry = 0
+
+ while l1 != nil || l2 != nil || carry != 0 {
+ let v1 = l1?.val ?? 0
+ let v2 = l2?.val ?? 0
+
+ let sum = v1 + v2 + carry
+ carry = sum / 10
+ let val = sum % 10
+ cur.next = ListNode(val)
+
+ cur = cur.next!
+ l1 = l1?.next
+ l2 = l2?.next
+ }
+ return dummy.next
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(m + n)$
-* Space complexity: $O(1)$
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(max(m, n))$ for the output list.
> Where $m$ is the length of $l1$ and $n$ is the length of $l2$.
\ No newline at end of file
diff --git a/articles/anagram-groups.md b/articles/anagram-groups.md
index a0aae3216..bf41aaa79 100644
--- a/articles/anagram-groups.md
+++ b/articles/anagram-groups.md
@@ -125,6 +125,21 @@ class Solution {
}
```
+```swift
+class Solution {
+ func groupAnagrams(_ strs: [String]) -> [[String]] {
+ var res = [String: [String]]()
+
+ for s in strs {
+ let sortedS = String(s.sorted())
+ res[sortedS, default: []].append(s)
+ }
+
+ return Array(res.values)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -277,11 +292,31 @@ class Solution {
}
```
+```swift
+class Solution {
+ func groupAnagrams(_ strs: [String]) -> [[String]] {
+ var res = [Array: [String]]()
+
+ for s in strs {
+ var count = [Int](repeating: 0, count: 26)
+ for c in s {
+ count[Int(c.asciiValue!) - 97] += 1
+ }
+ res[count, default: []].append(s)
+ }
+
+ return Array(res.values)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(m * n)$
-* Space complexity: $O(m)$
+* Space complexity:
+ * $O(m)$ extra space.
+ * $O(m * n)$ space for the output list.
-> Where $m$ is the number of strings and $n$ is the length of the longest string.
+> Where $m$ is the number of strings and $n$ is the length of the longest string.
\ No newline at end of file
diff --git a/articles/balanced-binary-tree.md b/articles/balanced-binary-tree.md
index c9c407ed0..21715bc6f 100644
--- a/articles/balanced-binary-tree.md
+++ b/articles/balanced-binary-tree.md
@@ -254,6 +254,43 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func isBalanced(_ root: TreeNode?) -> Bool {
+ guard let root = root else { return true }
+
+ let left = height(root.left)
+ let right = height(root.right)
+
+ if abs(left - right) > 1 {
+ return false
+ }
+
+ return isBalanced(root.left) && isBalanced(root.right)
+ }
+
+ private func height(_ root: TreeNode?) -> Int {
+ guard let root = root else { return 0 }
+ return 1 + max(height(root.left), height(root.right))
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -521,6 +558,39 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func isBalanced(_ root: TreeNode?) -> Bool {
+ return dfs(root).0
+ }
+
+ private func dfs(_ root: TreeNode?) -> (Bool, Int) {
+ guard let root = root else { return (true, 0) }
+
+ let left = dfs(root.left)
+ let right = dfs(root.right)
+
+ let balanced = left.0 && right.0 && abs(left.1 - right.1) <= 1
+ return (balanced, 1 + max(left.1, right.1))
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -534,7 +604,7 @@ class Solution {
---
-## 3. Depth First Search (Stack)
+## 3. Iterative DFS
::tabs-start
@@ -866,6 +936,58 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func isBalanced(_ root: TreeNode?) -> Bool {
+ var stack = [TreeNode]()
+ var node = root
+ var last: TreeNode? = nil
+ var depths = [ObjectIdentifier: Int]()
+
+ while !stack.isEmpty || node != nil {
+ if let current = node {
+ stack.append(current)
+ node = current.left
+ } else {
+ guard let current = stack.last else { break }
+ if current.right == nil || last === current.right {
+ stack.removeLast()
+
+ let leftDepth = current.left != nil ? depths[ObjectIdentifier(current.left!)] ?? 0 : 0
+ let rightDepth = current.right != nil ? depths[ObjectIdentifier(current.right!)] ?? 0 : 0
+ if abs(leftDepth - rightDepth) > 1 {
+ return false
+ }
+
+ depths[ObjectIdentifier(current)] = 1 + max(leftDepth, rightDepth)
+ last = current
+ node = nil
+ } else {
+ node = current.right
+ }
+ }
+ }
+
+ return true
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/binary-search.md b/articles/binary-search.md
index 5e88782ce..59a970a26 100644
--- a/articles/binary-search.md
+++ b/articles/binary-search.md
@@ -139,6 +139,29 @@ class Solution {
}
```
+```swift
+class Solution {
+ func binarySearch(_ l: Int, _ r: Int, _ nums: [Int], _ target: Int) -> Int {
+ if l > r {
+ return -1
+ }
+ let m = l + (r - l) / 2
+
+ if nums[m] == target {
+ return m
+ }
+ if nums[m] < target {
+ return binarySearch(m + 1, r, nums, target)
+ }
+ return binarySearch(l, m - 1, nums, target)
+ }
+
+ func search(_ nums: [Int], _ target: Int) -> Int {
+ return binarySearch(0, nums.count - 1, nums, target)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -296,6 +319,28 @@ class Solution {
}
```
+```swift
+class Solution {
+ func search(_ nums: [Int], _ target: Int) -> Int {
+ var l = 0, r = nums.count - 1
+
+ while l <= r {
+ // (l + r) // 2 can lead to overflow
+ let m = l + (r - l) / 2
+
+ if nums[m] > target {
+ r = m - 1
+ } else if nums[m] < target {
+ l = m + 1
+ } else {
+ return m
+ }
+ }
+ return -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -439,6 +484,24 @@ class Solution {
}
```
+```swift
+class Solution {
+ func search(_ nums: [Int], _ target: Int) -> Int {
+ var l = 0, r = nums.count
+
+ while l < r {
+ let m = l + (r - l) / 2
+ if nums[m] > target {
+ r = m
+ } else {
+ l = m + 1
+ }
+ }
+ return (l > 0 && nums[l - 1] == target) ? l - 1 : -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -582,6 +645,24 @@ class Solution {
}
```
+```swift
+class Solution {
+ func search(_ nums: [Int], _ target: Int) -> Int {
+ var l = 0, r = nums.count
+
+ while l < r {
+ let m = l + (r - l) / 2
+ if nums[m] >= target {
+ r = m
+ } else {
+ l = m + 1
+ }
+ }
+ return (l < nums.count && nums[l] == target) ? l : -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -664,6 +745,15 @@ class Solution {
}
```
+```swift
+class Solution {
+ func search(_ nums: [Int], _ target: Int) -> Int {
+ let index = nums.partitioningIndex { $0 >= target }
+ return (index < nums.count && nums[index] == target) ? index : -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/binary-tree-diameter.md b/articles/binary-tree-diameter.md
index 3c73fbe92..b11c3e40e 100644
--- a/articles/binary-tree-diameter.md
+++ b/articles/binary-tree-diameter.md
@@ -259,6 +259,41 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func diameterOfBinaryTree(_ root: TreeNode?) -> Int {
+ guard let root = root else { return 0 }
+
+ let leftHeight = maxHeight(root.left)
+ let rightHeight = maxHeight(root.right)
+ let diameter = leftHeight + rightHeight
+ let sub = max(diameterOfBinaryTree(root.left), diameterOfBinaryTree(root.right))
+
+ return max(diameter, sub)
+ }
+
+ private func maxHeight(_ root: TreeNode?) -> Int {
+ guard let root = root else { return 0 }
+ return 1 + max(maxHeight(root.left), maxHeight(root.right))
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -515,6 +550,40 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func diameterOfBinaryTree(_ root: TreeNode?) -> Int {
+ var res = 0
+
+ func dfs(_ root: TreeNode?) -> Int {
+ guard let root = root else { return 0 }
+ let left = dfs(root.left)
+ let right = dfs(root.right)
+ res = max(res, left + right)
+ return 1 + max(left, right)
+ }
+
+ dfs(root)
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -876,6 +945,49 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func diameterOfBinaryTree(_ root: TreeNode?) -> Int {
+ guard let root = root else { return 0 }
+ var stack: [TreeNode] = [root]
+ var mp = [ObjectIdentifier: (Int, Int)]()
+
+ while !stack.isEmpty {
+ let node = stack.last!
+ if let left = node.left, mp[ObjectIdentifier(left)] == nil {
+ stack.append(left)
+ } else if let right = node.right, mp[ObjectIdentifier(right)] == nil {
+ stack.append(right)
+ } else {
+ let node = stack.removeLast()
+ let leftTuple = node.left != nil ? mp[ObjectIdentifier(node.left!)]! : (0, 0)
+ let rightTuple = node.right != nil ? mp[ObjectIdentifier(node.right!)]! : (0, 0)
+ let height = 1 + max(leftTuple.0, rightTuple.0)
+ let diameter = max(leftTuple.0 + rightTuple.0, leftTuple.1, rightTuple.1)
+ mp[ObjectIdentifier(node)] = (height, diameter)
+ }
+ }
+
+ return mp[ObjectIdentifier(root)]!.1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/binary-tree-from-preorder-and-inorder-traversal.md b/articles/binary-tree-from-preorder-and-inorder-traversal.md
index 621fc91cd..b21106a35 100644
--- a/articles/binary-tree-from-preorder-and-inorder-traversal.md
+++ b/articles/binary-tree-from-preorder-and-inorder-traversal.md
@@ -235,6 +235,49 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func buildTree(_ preorder: [Int], _ inorder: [Int]) -> TreeNode? {
+ if preorder.isEmpty || inorder.isEmpty {
+ return nil
+ }
+
+ let rootValue = preorder[0]
+ let root = TreeNode(rootValue)
+ guard let mid = inorder.firstIndex(of: rootValue) else {
+ return root
+ }
+
+ root.left = buildTree(
+ Array(preorder[1..<(mid + 1)]),
+ Array(inorder[0.. TreeNode? {
+ for (index, value) in inorder.enumerated() {
+ indexMap[value] = index
+ }
+ return dfs(preorder, 0, inorder.count - 1)
+ }
+
+ private func dfs(_ preorder: [Int], _ left: Int, _ right: Int) -> TreeNode? {
+ if left > right {
+ return nil
+ }
+
+ let rootVal = preorder[preIndex]
+ preIndex += 1
+ let root = TreeNode(rootVal)
+ let mid = indexMap[rootVal]!
+
+ root.left = dfs(preorder, left, mid - 1)
+ root.right = dfs(preorder, mid + 1, right)
+
+ return root
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -775,6 +863,48 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ var preIdx = 0
+ var inIdx = 0
+
+ func buildTree(_ preorder: [Int], _ inorder: [Int]) -> TreeNode? {
+ return dfs(preorder, inorder, Int.max)
+ }
+
+ private func dfs(_ preorder: [Int], _ inorder: [Int], _ limit: Int) -> TreeNode? {
+ if preIdx >= preorder.count {
+ return nil
+ }
+ if inorder[inIdx] == limit {
+ inIdx += 1
+ return nil
+ }
+
+ let root = TreeNode(preorder[preIdx])
+ preIdx += 1
+ root.left = dfs(preorder, inorder, root.val)
+ root.right = dfs(preorder, inorder, limit)
+ return root
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/binary-tree-maximum-path-sum.md b/articles/binary-tree-maximum-path-sum.md
index af442201a..ebd5467bc 100644
--- a/articles/binary-tree-maximum-path-sum.md
+++ b/articles/binary-tree-maximum-path-sum.md
@@ -290,6 +290,49 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ var res = Int.min
+
+ func maxPathSum(_ root: TreeNode?) -> Int {
+ dfs(root)
+ return res
+ }
+
+ private func dfs(_ root: TreeNode?) {
+ guard let node = root else { return }
+ let left = getMax(node.left)
+ let right = getMax(node.right)
+ res = max(res, node.val + left + right)
+ dfs(node.left)
+ dfs(node.right)
+ }
+
+ private func getMax(_ root: TreeNode?) -> Int {
+ guard let node = root else { return 0 }
+ let left = getMax(node.left)
+ let right = getMax(node.right)
+ let path = node.val + max(left, right)
+ return max(0, path)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -560,6 +603,42 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func maxPathSum(_ root: TreeNode?) -> Int {
+ var res = root!.val
+
+ func dfs(_ root: TreeNode?) -> Int {
+ guard let node = root else { return 0 }
+
+ let leftMax = max(dfs(node.left), 0)
+ let rightMax = max(dfs(node.right), 0)
+
+ res = max(res, node.val + leftMax + rightMax)
+ return node.val + max(leftMax, rightMax)
+ }
+
+ dfs(root)
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/binary-tree-right-side-view.md b/articles/binary-tree-right-side-view.md
index e17b22299..4d8a68b19 100644
--- a/articles/binary-tree-right-side-view.md
+++ b/articles/binary-tree-right-side-view.md
@@ -236,6 +236,42 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func rightSideView(_ root: TreeNode?) -> [Int] {
+ var res = [Int]()
+
+ func dfs(_ node: TreeNode?, _ depth: Int) {
+ guard let node = node else { return }
+ if depth == res.count {
+ res.append(node.val)
+ }
+
+ dfs(node.right, depth + 1)
+ dfs(node.left, depth + 1)
+ }
+
+ dfs(root, 0)
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -530,6 +566,48 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func rightSideView(_ root: TreeNode?) -> [Int] {
+ var res = [Int]()
+ var q = Deque()
+ q.append(root)
+
+ while !q.isEmpty {
+ var rightSide: TreeNode?
+ let qLen = q.count
+
+ for _ in 0.. Int {
+ var nums = [1] + nums + [1]
+
+ func dfs(_ nums: [Int]) -> Int {
+ if nums.count == 2 {
+ return 0
+ }
+
+ var maxCoins = 0
+ for i in 1..<(nums.count - 1) {
+ let coins = nums[i - 1] * nums[i] * nums[i + 1] +
+ dfs(Array(nums[.. Int {
+ var nums = [1] + nums + [1]
+ let n = nums.count
+ var dp = Array(repeating: Array(repeating: -1, count: n), count: n)
+
+ func dfs(_ l: Int, _ r: Int) -> Int {
+ if l > r {
+ return 0
+ }
+ if dp[l][r] != -1 {
+ return dp[l][r]
+ }
+
+ dp[l][r] = 0
+ for i in l...r {
+ let coins = nums[l - 1] * nums[i] * nums[r + 1] + dfs(l, i - 1) + dfs(i + 1, r)
+ dp[l][r] = max(dp[l][r], coins)
+ }
+ return dp[l][r]
+ }
+
+ return dfs(1, n - 2)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -621,6 +673,29 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxCoins(_ nums: [Int]) -> Int {
+ let n = nums.count
+ var newNums = [1] + nums + [1]
+
+ var dp = Array(repeating: Array(repeating: 0, count: n + 2), count: n + 2)
+
+ for l in stride(from: n, through: 1, by: -1) {
+ for r in l...n {
+ for i in l...r {
+ let coins = (newNums[l - 1] * newNums[i] * newNums[r + 1]) +
+ dp[l][i - 1] + dp[i + 1][r]
+ dp[l][r] = max(dp[l][r], coins)
+ }
+ }
+ }
+
+ return dp[1][n]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/buy-and-sell-crypto-with-cooldown.md b/articles/buy-and-sell-crypto-with-cooldown.md
index 366028454..9c4ae550b 100644
--- a/articles/buy-and-sell-crypto-with-cooldown.md
+++ b/articles/buy-and-sell-crypto-with-cooldown.md
@@ -171,6 +171,31 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxProfit(_ prices: [Int]) -> Int {
+ let n = prices.count
+
+ func dfs(_ i: Int, _ buying: Bool) -> Int {
+ if i >= n {
+ return 0
+ }
+
+ let cooldown = dfs(i + 1, buying)
+ if buying {
+ let buy = dfs(i + 1, false) - prices[i]
+ return max(buy, cooldown)
+ } else {
+ let sell = dfs(i + 2, true) + prices[i]
+ return max(sell, cooldown)
+ }
+ }
+
+ return dfs(0, true)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -412,6 +437,36 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxProfit(_ prices: [Int]) -> Int {
+ let n = prices.count
+ var dp = [[Int?]](repeating: [Int?](repeating: nil, count: 2), count: n)
+
+ func dfs(_ i: Int, _ buying: Int) -> Int {
+ if i >= n {
+ return 0
+ }
+ if let cached = dp[i][buying] {
+ return cached
+ }
+
+ let cooldown = dfs(i + 1, buying)
+ if buying == 1 {
+ let buy = dfs(i + 1, 0) - prices[i]
+ dp[i][buying] = max(buy, cooldown)
+ } else {
+ let sell = dfs(i + 2, 1) + prices[i]
+ dp[i][buying] = max(sell, cooldown)
+ }
+ return dp[i][buying]!
+ }
+
+ return dfs(0, 1)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -611,6 +666,31 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxProfit(_ prices: [Int]) -> Int {
+ let n = prices.count
+ var dp = Array(repeating: [0, 0], count: n + 1)
+
+ for i in stride(from: n - 1, through: 0, by: -1) {
+ for buying in 0...1 {
+ if buying == 1 {
+ let buy = (i + 1 < n ? dp[i + 1][0] - prices[i] : -prices[i])
+ let cooldown = (i + 1 < n ? dp[i + 1][1] : 0)
+ dp[i][1] = max(buy, cooldown)
+ } else {
+ let sell = (i + 2 < n ? dp[i + 2][1] + prices[i] : prices[i])
+ let cooldown = (i + 1 < n ? dp[i + 1][0] : 0)
+ dp[i][0] = max(sell, cooldown)
+ }
+ }
+ }
+
+ return dp[0][1]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -769,6 +849,26 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxProfit(_ prices: [Int]) -> Int {
+ let n = prices.count
+ var dp1Buy = 0, dp1Sell = 0
+ var dp2Buy = 0
+
+ for i in stride(from: n - 1, through: 0, by: -1) {
+ let dpBuy = max(dp1Sell - prices[i], dp1Buy)
+ let dpSell = max(dp2Buy + prices[i], dp1Sell)
+ dp2Buy = dp1Buy
+ dp1Buy = dpBuy
+ dp1Sell = dpSell
+ }
+
+ return dp1Buy
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/buy-and-sell-crypto.md b/articles/buy-and-sell-crypto.md
index 0e618efd5..b983fd272 100644
--- a/articles/buy-and-sell-crypto.md
+++ b/articles/buy-and-sell-crypto.md
@@ -120,6 +120,22 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxProfit(_ prices: [Int]) -> Int {
+ var res = 0
+ for i in 0.. Int {
+ var l = 0, r = 1
+ var maxP = 0
+
+ while r < prices.count {
+ if prices[l] < prices[r] {
+ let profit = prices[r] - prices[l]
+ maxP = max(maxP, profit)
+ } else {
+ l = r
+ }
+ r += 1
+ }
+ return maxP
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -397,6 +433,21 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxProfit(_ prices: [Int]) -> Int {
+ var maxP = 0
+ var minBuy = prices[0]
+
+ for sell in prices {
+ maxP = max(maxP, sell - minBuy)
+ minBuy = min(minBuy, sell)
+ }
+ return maxP
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/car-fleet.md b/articles/car-fleet.md
index 2d4e2ef35..22c7a9d0f 100644
--- a/articles/car-fleet.md
+++ b/articles/car-fleet.md
@@ -150,6 +150,26 @@ class Solution {
}
```
+```swift
+class Solution {
+ func carFleet(_ target: Int, _ position: [Int], _ speed: [Int]) -> Int {
+ var pair = zip(position, speed).map { ($0, $1) }
+ pair.sort { $0.0 > $1.0 } // Sort in descending order by position
+
+ var stack = [Double]()
+
+ for (p, s) in pair {
+ stack.append(Double(target - p) / Double(s))
+ if stack.count >= 2 && stack.last! <= stack[stack.count - 2] {
+ stack.removeLast()
+ }
+ }
+
+ return stack.count
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -327,6 +347,30 @@ class Solution {
}
```
+```swift
+class Solution {
+ func carFleet(_ target: Int, _ position: [Int], _ speed: [Int]) -> Int {
+ var pair = zip(position, speed).map { ($0, $1) }
+ pair.sort { $0.0 > $1.0 } // Sort in descending order by position
+
+ var fleets = 1
+ var prevTime = Double(target - pair[0].0) / Double(pair[0].1)
+
+ for i in 1.. prevTime {
+ fleets += 1
+ prevTime = currTime
+ }
+ }
+
+ return fleets
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/cheapest-flight-path.md b/articles/cheapest-flight-path.md
index 6c23351be..976640249 100644
--- a/articles/cheapest-flight-path.md
+++ b/articles/cheapest-flight-path.md
@@ -258,6 +258,53 @@ class Solution {
}
```
+```swift
+struct Item: Comparable {
+ let cost: Int
+ let node: Int
+ let stops: Int
+
+ static func < (lhs: Item, rhs: Item) -> Bool {
+ return lhs.cost < rhs.cost
+ }
+}
+
+class Solution {
+ func findCheapestPrice(_ n: Int, _ flights: [[Int]], _ src: Int, _ dst: Int, _ k: Int) -> Int {
+ let INF = Int.max
+ var adj = Array(repeating: [(Int, Int)](), count: n)
+ var dist = Array(repeating: Array(repeating: INF, count: k + 5), count: n)
+
+ for flight in flights {
+ let u = flight[0], v = flight[1], cst = flight[2]
+ adj[u].append((v, cst))
+ }
+
+ var minHeap = Heap- ()
+ minHeap.insert(Item(cost: 0, node: src, stops: -1))
+ dist[src][0] = 0
+
+ while !minHeap.isEmpty {
+ let item = minHeap.removeMin()
+ let cst = item.cost, node = item.node, stops = item.stops
+ if node == dst { return cst }
+ if stops == k || dist[node][stops + 1] < cst { continue }
+
+ for (nei, w) in adj[node] {
+ let nextCst = cst + w
+ let nextStops = stops + 1
+ if dist[nei][nextStops + 1] > nextCst {
+ dist[nei][nextStops + 1] = nextCst
+ minHeap.insert(Item(cost: nextCst, node: nei, stops: nextStops))
+ }
+ }
+ }
+
+ return -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -471,6 +518,31 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findCheapestPrice(_ n: Int, _ flights: [[Int]], _ src: Int, _ dst: Int, _ k: Int) -> Int {
+ var prices = Array(repeating: Int.max, count: n)
+ prices[src] = 0
+
+ for _ in 0...k {
+ var tmpPrices = prices
+
+ for flight in flights {
+ let s = flight[0], d = flight[1], p = flight[2]
+ if prices[s] == Int.max {
+ continue
+ }
+ if prices[s] + p < tmpPrices[d] {
+ tmpPrices[d] = prices[s] + p
+ }
+ }
+ prices = tmpPrices
+ }
+ return prices[dst] == Int.max ? -1 : prices[dst]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -727,6 +799,41 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findCheapestPrice(_ n: Int, _ flights: [[Int]], _ src: Int, _ dst: Int, _ k: Int) -> Int {
+ var prices = Array(repeating: Int.max, count: n)
+ prices[src] = 0
+ var adj = Array(repeating: [(Int, Int)](), count: n)
+
+ for flight in flights {
+ let u = flight[0], v = flight[1], cst = flight[2]
+ adj[u].append((v, cst))
+ }
+
+ var queue = Deque<(Int, Int, Int)>()
+ queue.append((0, src, 0))
+
+ while !queue.isEmpty {
+ let (cst, node, stops) = queue.popFirst()!
+ if stops > k {
+ continue
+ }
+
+ for (nei, w) in adj[node] {
+ let nextCost = cst + w
+ if nextCost < prices[nei] {
+ prices[nei] = nextCost
+ queue.append((nextCost, nei, stops + 1))
+ }
+ }
+ }
+
+ return prices[dst] == Int.max ? -1 : prices[dst]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/climbing-stairs.md b/articles/climbing-stairs.md
index a1a70e0fa..126511582 100644
--- a/articles/climbing-stairs.md
+++ b/articles/climbing-stairs.md
@@ -99,6 +99,21 @@ class Solution {
}
```
+```swift
+class Solution {
+ func climbStairs(_ n: Int) -> Int {
+ func dfs(_ i: Int) -> Int {
+ if i >= n {
+ return i == n ? 1 : 0
+ }
+ return dfs(i + 1) + dfs(i + 2)
+ }
+
+ return dfs(0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -240,6 +255,27 @@ class Solution {
}
```
+```swift
+class Solution {
+ func climbStairs(_ n: Int) -> Int {
+ var cache = Array(repeating: -1, count: n)
+
+ func dfs(_ i: Int) -> Int {
+ if i >= n {
+ return i == n ? 1 : 0
+ }
+ if cache[i] != -1 {
+ return cache[i]
+ }
+ cache[i] = dfs(i + 1) + dfs(i + 2)
+ return cache[i]
+ }
+
+ return dfs(0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -368,6 +404,23 @@ class Solution {
}
```
+```swift
+class Solution {
+ func climbStairs(_ n: Int) -> Int {
+ if n <= 2 {
+ return n
+ }
+ var dp = Array(repeating: 0, count: n + 1)
+ dp[1] = 1
+ dp[2] = 2
+ for i in 3...n {
+ dp[i] = dp[i - 1] + dp[i - 2]
+ }
+ return dp[n]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -495,6 +548,22 @@ class Solution {
}
```
+```swift
+class Solution {
+ func climbStairs(_ n: Int) -> Int {
+ var one = 1, two = 1
+
+ for _ in 0..<(n - 1) {
+ let temp = one
+ one = one + two
+ two = temp
+ }
+
+ return one
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -764,6 +833,45 @@ class Solution {
}
```
+```swift
+class Solution {
+ func climbStairs(_ n: Int) -> Int {
+ if n == 1 {
+ return 1
+ }
+
+ func matrixMult(_ A: [[Int]], _ B: [[Int]]) -> [[Int]] {
+ return [
+ [A[0][0] * B[0][0] + A[0][1] * B[1][0],
+ A[0][0] * B[0][1] + A[0][1] * B[1][1]],
+ [A[1][0] * B[0][0] + A[1][1] * B[1][0],
+ A[1][0] * B[0][1] + A[1][1] * B[1][1]]
+ ]
+ }
+
+ func matrixPow(_ M: [[Int]], _ p: Int) -> [[Int]] {
+ var result = [[1, 0], [0, 1]]
+ var base = M
+ var power = p
+
+ while power > 0 {
+ if power % 2 == 1 {
+ result = matrixMult(result, base)
+ }
+ base = matrixMult(base, base)
+ power /= 2
+ }
+
+ return result
+ }
+
+ let M = [[1, 1], [1, 0]]
+ let result = matrixPow(M, n)
+ return result[0][0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -865,6 +973,18 @@ class Solution {
}
```
+```swift
+class Solution {
+ func climbStairs(_ n: Int) -> Int {
+ let sqrt5 = sqrt(5.0)
+ let phi = (1.0 + sqrt5) / 2.0
+ let psi = (1.0 - sqrt5) / 2.0
+ let n = n + 1
+ return Int(round((pow(phi, Double(n)) - pow(psi, Double(n))) / sqrt5))
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/clone-graph.md b/articles/clone-graph.md
index ff2612c4c..e71e55184 100644
--- a/articles/clone-graph.md
+++ b/articles/clone-graph.md
@@ -290,6 +290,47 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a Node.
+ * public class Node {
+ * public var val: Int
+ * public var neighbors: [Node?]
+ * public init(_ val: Int) {
+ * self.val = val
+ * self.neighbors = []
+ * }
+ * }
+ */
+
+class Solution {
+ func cloneGraph(_ node: Node?) -> Node? {
+ var oldToNew = [Node: Node]()
+
+ func dfs(_ node: Node?) -> Node? {
+ guard let node = node else { return nil }
+
+ if let existingCopy = oldToNew[node] {
+ return existingCopy
+ }
+
+ let copy = Node(node.val)
+ oldToNew[node] = copy
+
+ for neighbor in node.neighbors {
+ if let clonedNeighbor = dfs(neighbor) {
+ copy.neighbors.append(clonedNeighbor)
+ }
+ }
+
+ return copy
+ }
+
+ return dfs(node)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -582,6 +623,49 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a Node.
+ * public class Node {
+ * public var val: Int
+ * public var neighbors: [Node?]
+ * public init(_ val: Int) {
+ * self.val = val
+ * self.neighbors = []
+ * }
+ * }
+ */
+
+class Solution {
+ func cloneGraph(_ node: Node?) -> Node? {
+ if node == nil {
+ return nil
+ }
+
+ var oldToNew: [Node: Node] = [:]
+ let newNode = Node(node!.val)
+ oldToNew[node!] = newNode
+ var queue = Deque()
+ queue.append(node!)
+
+ while !queue.isEmpty {
+ let cur = queue.popFirst()!
+ for nei in cur.neighbors {
+ if let nei = nei {
+ if oldToNew[nei] == nil {
+ oldToNew[nei] = Node(nei.val)
+ queue.append(nei)
+ }
+ oldToNew[cur]!.neighbors.append(oldToNew[nei]!)
+ }
+ }
+ }
+
+ return oldToNew[node!]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/coin-change-ii.md b/articles/coin-change-ii.md
index cdfd83983..6e4cce788 100644
--- a/articles/coin-change-ii.md
+++ b/articles/coin-change-ii.md
@@ -178,6 +178,32 @@ class Solution {
}
```
+```swift
+class Solution {
+ func change(_ amount: Int, _ coins: [Int]) -> Int {
+ let coins = coins.sorted()
+
+ func dfs(_ i: Int, _ a: Int) -> Int {
+ if a == 0 {
+ return 1
+ }
+ if i >= coins.count {
+ return 0
+ }
+
+ var res = 0
+ if a >= coins[i] {
+ res = dfs(i + 1, a)
+ res += dfs(i, a - coins[i])
+ }
+ return res
+ }
+
+ return dfs(0, amount)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -399,6 +425,38 @@ class Solution {
}
```
+```swift
+class Solution {
+ func change(_ amount: Int, _ coins: [Int]) -> Int {
+ let coins = coins.sorted()
+ var memo = Array(repeating: Array(repeating: -1, count: amount + 1), count: coins.count + 1)
+
+ func dfs(_ i: Int, _ a: Int) -> Int {
+ if a == 0 {
+ return 1
+ }
+ if i >= coins.count {
+ return 0
+ }
+ if memo[i][a] != -1 {
+ return memo[i][a]
+ }
+
+ var res = 0
+ if a >= coins[i] {
+ res = dfs(i + 1, a)
+ res += dfs(i, a - coins[i])
+ }
+
+ memo[i][a] = res
+ return res
+ }
+
+ return dfs(0, amount)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -464,8 +522,8 @@ public:
int change(int amount, vector& coins) {
int n = coins.size();
sort(coins.begin(), coins.end());
- vector> dp(n + 1, vector(amount + 1, 0));
-
+ vector> dp(n + 1, vector(amount + 1, 0));
+
for (int i = 0; i <= n; i++) {
dp[i][0] = 1;
}
@@ -592,6 +650,41 @@ class Solution {
}
```
+```swift
+class Solution {
+ func change(_ amount: Int, _ coins: [Int]) -> Int {
+ let n = coins.count
+ let sortedCoins = coins.sorted()
+ var dp = Array(
+ repeating: Array(repeating: 0, count: amount + 1),
+ count: n + 1
+ )
+
+ for i in 0...n {
+ dp[i][0] = 1
+ }
+
+ for i in stride(from: n - 1, through: 0, by: -1) {
+ for a in 0...amount {
+ let base = dp[i + 1][a]
+ if a >= sortedCoins[i] {
+ let addend = dp[i][a - sortedCoins[i]]
+ if base > Int.max - addend {
+ dp[i][a] = 0
+ } else {
+ dp[i][a] = base + addend
+ }
+ } else {
+ dp[i][a] = base
+ }
+ }
+ }
+
+ return dp[0][amount]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -650,10 +743,10 @@ public class Solution {
class Solution {
public:
int change(int amount, vector& coins) {
- vector dp(amount + 1, 0);
+ vector dp(amount + 1, 0);
dp[0] = 1;
for (int i = coins.size() - 1; i >= 0; i--) {
- vector nextDP(amount + 1, 0);
+ vector nextDP(amount + 1, 0);
nextDP[0] = 1;
for (int a = 1; a <= amount; a++) {
@@ -764,6 +857,36 @@ class Solution {
}
```
+```swift
+class Solution {
+ func change(_ amount: Int, _ coins: [Int]) -> Int {
+ var dp = [Int](repeating: 0, count: amount + 1)
+ dp[0] = 1
+
+ for i in stride(from: coins.count - 1, through: 0, by: -1) {
+ var nextDP = [Int](repeating: 0, count: amount + 1)
+ nextDP[0] = 1
+
+ for a in 1..<(amount + 1) {
+ nextDP[a] = dp[a]
+ if a - coins[i] >= 0 {
+ let addend = nextDP[a - coins[i]]
+ if nextDP[a] > Int.max - addend {
+ nextDP[a] = 0
+ } else {
+ nextDP[a] += addend
+ }
+ }
+ }
+
+ dp = nextDP
+ }
+
+ return dp[amount]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -807,7 +930,7 @@ public class Solution {
class Solution {
public:
int change(int amount, vector& coins) {
- vector dp(amount + 1, 0);
+ vector dp(amount + 1, 0);
dp[0] = 1;
for (int i = coins.size() - 1; i >= 0; i--) {
for (int a = 1; a <= amount; a++) {
@@ -890,6 +1013,30 @@ class Solution {
}
```
+```swift
+class Solution {
+ func change(_ amount: Int, _ coins: [Int]) -> Int {
+ var dp = [Int](repeating: 0, count: amount + 1)
+ dp[0] = 1
+
+ for i in stride(from: coins.count - 1, through: 0, by: -1) {
+ for a in 1..<(amount + 1) {
+ if coins[i] <= a {
+ let addend = dp[a - coins[i]]
+ if dp[a] > Int.max - addend {
+ dp[a] = 0
+ } else {
+ dp[a] += addend
+ }
+ }
+ }
+ }
+
+ return dp[amount]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/coin-change.md b/articles/coin-change.md
index eb1f7e715..f61f99922 100644
--- a/articles/coin-change.md
+++ b/articles/coin-change.md
@@ -170,6 +170,29 @@ class Solution {
}
```
+```swift
+class Solution {
+ func coinChange(_ coins: [Int], _ amount: Int) -> Int {
+ func dfs(_ amount: Int) -> Int {
+ if amount == 0 {
+ return 0
+ }
+
+ var res = Int(1e9)
+ for coin in coins {
+ if amount - coin >= 0 {
+ res = min(res, 1 + dfs(amount - coin))
+ }
+ }
+ return res
+ }
+
+ let minCoins = dfs(amount)
+ return minCoins >= Int(1e9) ? -1 : minCoins
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -393,6 +416,36 @@ class Solution {
}
```
+```swift
+class Solution {
+ func coinChange(_ coins: [Int], _ amount: Int) -> Int {
+ var memo = [Int: Int]()
+
+ func dfs(_ amount: Int) -> Int {
+ if amount == 0 {
+ return 0
+ }
+ if let cached = memo[amount] {
+ return cached
+ }
+
+ var res = Int(1e9)
+ for coin in coins {
+ if amount - coin >= 0 {
+ res = min(res, 1 + dfs(amount - coin))
+ }
+ }
+
+ memo[amount] = res
+ return res
+ }
+
+ let minCoins = dfs(amount)
+ return minCoins >= Int(1e9) ? -1 : minCoins
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -542,6 +595,29 @@ class Solution {
}
```
+```swift
+class Solution {
+ func coinChange(_ coins: [Int], _ amount: Int) -> Int {
+ if amount == 0 {
+ return 0
+ }
+
+ var dp = [Int](repeating: amount + 1, count: amount + 1)
+ dp[0] = 0
+
+ for a in 1...amount {
+ for coin in coins {
+ if a - coin >= 0 {
+ dp[a] = min(dp[a], 1 + dp[a - coin])
+ }
+ }
+ }
+
+ return dp[amount] == amount + 1 ? -1 : dp[amount]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -772,6 +848,41 @@ class Solution {
}
```
+```swift
+class Solution {
+ func coinChange(_ coins: [Int], _ amount: Int) -> Int {
+ if amount == 0 {
+ return 0
+ }
+
+ var q = Deque([0])
+ var seen = Array(repeating: false, count: amount + 1)
+ seen[0] = true
+ var res = 0
+
+ while !q.isEmpty {
+ res += 1
+ for _ in 0.. amount || seen[nxt] {
+ continue
+ }
+ seen[nxt] = true
+ q.append(nxt)
+ }
+ }
+ }
+
+ return -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/combination-target-sum-ii.md b/articles/combination-target-sum-ii.md
index 0c9a90f24..3b35aab6d 100644
--- a/articles/combination-target-sum-ii.md
+++ b/articles/combination-target-sum-ii.md
@@ -216,6 +216,35 @@ class Solution {
}
```
+```swift
+class Solution {
+ func combinationSum2(_ candidates: [Int], _ target: Int) -> [[Int]] {
+ var res = Set<[Int]>()
+ let sortedCandidates = candidates.sorted()
+
+ func generateSubsets(_ i: Int, _ cur: inout [Int], _ total: Int) {
+ if total == target {
+ res.insert(cur)
+ return
+ }
+ if total > target || i == sortedCandidates.count {
+ return
+ }
+
+ cur.append(sortedCandidates[i])
+ generateSubsets(i + 1, &cur, total + sortedCandidates[i])
+ cur.removeLast()
+
+ generateSubsets(i + 1, &cur, total)
+ }
+
+ var cur: [Int] = []
+ generateSubsets(0, &cur, 0)
+ return Array(res)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -464,6 +493,39 @@ class Solution {
}
```
+```swift
+class Solution {
+ func combinationSum2(_ candidates: [Int], _ target: Int) -> [[Int]] {
+ var res = [[Int]]()
+ let sortedCandidates = candidates.sorted()
+
+ func dfs(_ i: Int, _ cur: inout [Int], _ total: Int) {
+ if total == target {
+ res.append(cur)
+ return
+ }
+ if total > target || i == sortedCandidates.count {
+ return
+ }
+
+ cur.append(sortedCandidates[i])
+ dfs(i + 1, &cur, total + sortedCandidates[i])
+ cur.removeLast()
+
+ var j = i
+ while j + 1 < sortedCandidates.count && sortedCandidates[j] == sortedCandidates[j + 1] {
+ j += 1
+ }
+ dfs(j + 1, &cur, total)
+ }
+
+ var cur: [Int] = []
+ dfs(0, &cur, 0)
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -772,6 +834,47 @@ class Solution {
}
```
+```swift
+class Solution {
+ func combinationSum2(_ nums: [Int], _ target: Int) -> [[Int]] {
+ var res = [[Int]]()
+ var count = [Int: Int]()
+ var uniqueNums = [Int]()
+
+ for num in nums {
+ if count[num] == nil {
+ uniqueNums.append(num)
+ }
+ count[num, default: 0] += 1
+ }
+
+ func backtrack(_ nums: [Int], _ target: Int, _ cur: inout [Int], _ i: Int) {
+ if target == 0 {
+ res.append(cur)
+ return
+ }
+ if target < 0 || i >= nums.count {
+ return
+ }
+
+ if count[nums[i], default: 0] > 0 {
+ cur.append(nums[i])
+ count[nums[i], default: 0] -= 1
+ backtrack(nums, target - nums[i], &cur, i)
+ count[nums[i], default: 0] += 1
+ cur.removeLast()
+ }
+
+ backtrack(nums, target, &cur, i + 1)
+ }
+
+ var cur: [Int] = []
+ backtrack(uniqueNums, target, &cur, 0)
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1008,6 +1111,39 @@ class Solution {
}
```
+```swift
+class Solution {
+ func combinationSum2(_ candidates: [Int], _ target: Int) -> [[Int]] {
+ var res = [[Int]]()
+ let sortedCandidates = candidates.sorted()
+
+ func dfs(_ idx: Int, _ path: inout [Int], _ cur: Int) {
+ if cur == target {
+ res.append(path)
+ return
+ }
+
+ for i in idx.. idx && sortedCandidates[i] == sortedCandidates[i - 1] {
+ continue
+ }
+ if cur + sortedCandidates[i] > target {
+ break
+ }
+
+ path.append(sortedCandidates[i])
+ dfs(i + 1, &path, cur + sortedCandidates[i])
+ path.removeLast()
+ }
+ }
+
+ var path: [Int] = []
+ dfs(0, &path, 0)
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/combination-target-sum.md b/articles/combination-target-sum.md
index 43a9f3cd1..46436ad64 100644
--- a/articles/combination-target-sum.md
+++ b/articles/combination-target-sum.md
@@ -194,6 +194,33 @@ class Solution {
}
```
+```swift
+class Solution {
+ func combinationSum(_ nums: [Int], _ target: Int) -> [[Int]] {
+ var res: [[Int]] = []
+
+ func dfs(_ i: Int, _ cur: inout [Int], _ total: Int) {
+ if total == target {
+ res.append(cur)
+ return
+ }
+ if i >= nums.count || total > target {
+ return
+ }
+
+ cur.append(nums[i])
+ dfs(i, &cur, total + nums[i])
+ cur.removeLast()
+ dfs(i + 1, &cur, total)
+ }
+
+ var cur: [Int] = []
+ dfs(0, &cur, 0)
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -406,6 +433,35 @@ class Solution {
}
```
+```swift
+class Solution {
+ func combinationSum(_ nums: [Int], _ target: Int) -> [[Int]] {
+ var res: [[Int]] = []
+ let sortedNums = nums.sorted()
+
+ func dfs(_ i: Int, _ cur: inout [Int], _ total: Int) {
+ if total == target {
+ res.append(cur)
+ return
+ }
+
+ for j in i.. target {
+ return
+ }
+ cur.append(sortedNums[j])
+ dfs(j, &cur, total + sortedNums[j])
+ cur.removeLast()
+ }
+ }
+
+ var cur: [Int] = []
+ dfs(0, &cur, 0)
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/combinations-of-a-phone-number.md b/articles/combinations-of-a-phone-number.md
index 941f7ebf6..6f6bfd6dd 100644
--- a/articles/combinations-of-a-phone-number.md
+++ b/articles/combinations-of-a-phone-number.md
@@ -212,12 +212,45 @@ class Solution {
}
```
+```swift
+class Solution {
+ func letterCombinations(_ digits: String) -> [String] {
+ guard !digits.isEmpty else { return [] }
+
+ let digitToChar: [Character: String] = [
+ "2": "abc", "3": "def", "4": "ghi", "5": "jkl",
+ "6": "mno", "7": "pqrs", "8": "tuv", "9": "wxyz"
+ ]
+
+ var res = [String]()
+ let digitsArray = Array(digits)
+
+ func backtrack(_ i: Int, _ curStr: String) {
+ if curStr.count == digits.count {
+ res.append(curStr)
+ return
+ }
+ if let letters = digitToChar[digitsArray[i]] {
+ for c in letters {
+ backtrack(i + 1, curStr + String(c))
+ }
+ }
+ }
+
+ backtrack(0, "")
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(n * 4 ^ n)$
-* Space complexity: $O(n)$
+* Space complexity:
+ * $O(n)$ extra space.
+ * $O(n * 4 ^ n)$ space for the output list.
---
@@ -429,9 +462,39 @@ class Solution {
}
```
+```swift
+class Solution {
+ func letterCombinations(_ digits: String) -> [String] {
+ guard !digits.isEmpty else { return [] }
+
+ let digitToChar: [Character: String] = [
+ "2": "abc", "3": "def", "4": "ghi", "5": "jkl",
+ "6": "mno", "7": "pqrs", "8": "tuv", "9": "wxyz"
+ ]
+
+ var res = [""]
+
+ for digit in digits {
+ guard let letters = digitToChar[digit] else { continue }
+ var tmp = [String]()
+ for curStr in res {
+ for c in letters {
+ tmp.append(curStr + String(c))
+ }
+ }
+ res = tmp
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(n * 4 ^ n)$
-* Space complexity: $O(n)$
\ No newline at end of file
+* Space complexity:
+ * $O(n)$ extra space.
+ * $O(n * 4 ^ n)$ space for the output list.
\ No newline at end of file
diff --git a/articles/copy-linked-list-with-random-pointer.md b/articles/copy-linked-list-with-random-pointer.md
index 2c8acaed9..0b595bf64 100644
--- a/articles/copy-linked-list-with-random-pointer.md
+++ b/articles/copy-linked-list-with-random-pointer.md
@@ -1,4 +1,4 @@
-## 1. Hash Map (Recursion)
+## 1. Recursion + Hash Map
::tabs-start
@@ -223,6 +223,44 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a Node.
+ * public class Node {
+ * public var val: Int
+ * public var next: Node?
+ * public var random: Node?
+ * public init(_ val: Int) {
+ * self.val = val
+ * self.next = nil
+ * self.random = nil
+ * }
+ * }
+ */
+
+class Solution {
+ private var map = [Node: Node]()
+
+ func copyRandomList(_ head: Node?) -> Node? {
+ if head == nil {
+ return nil
+ }
+
+ if let copied = map[head!] {
+ return copied
+ }
+
+ let copy = Node(head!.val)
+ map[head!] = copy
+
+ copy.next = copyRandomList(head!.next)
+ copy.random = copyRandomList(head!.random)
+
+ return copy
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -494,6 +532,45 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a Node.
+ * public class Node {
+ * public var val: Int
+ * public var next: Node?
+ * public var random: Node?
+ * public init(_ val: Int) {
+ * self.val = val
+ * self.next = nil
+ * self.random = nil
+ * }
+ * }
+ */
+
+class Solution {
+ func copyRandomList(_ head: Node?) -> Node? {
+ var oldToCopy: [Node?: Node?] = [nil: nil]
+
+ var cur = head
+ while cur != nil {
+ let copy = Node(cur!.val)
+ oldToCopy[cur] = copy
+ cur = cur?.next
+ }
+
+ cur = head
+ while cur != nil {
+ let copy = oldToCopy[cur]!
+ copy?.next = oldToCopy[cur?.next]!
+ copy?.random = oldToCopy[cur?.random]!
+ cur = cur?.next
+ }
+
+ return oldToCopy[head]!
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -789,6 +866,46 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a Node.
+ * public class Node {
+ * public var val: Int
+ * public var next: Node?
+ * public var random: Node?
+ * public init(_ val: Int) {
+ * self.val = val
+ * self.next = nil
+ * self.random = nil
+ * }
+ * }
+ */
+
+class Solution {
+ func copyRandomList(_ head: Node?) -> Node? {
+ var oldToCopy = [Node?: Node?]()
+
+ func getNode(_ node: Node?) -> Node? {
+ if node == nil { return nil }
+ if oldToCopy[node] == nil {
+ oldToCopy[node] = Node(0)
+ }
+ return oldToCopy[node]!
+ }
+
+ var cur = head
+ while cur != nil {
+ getNode(cur)!.val = cur!.val
+ getNode(cur)!.next = getNode(cur!.next)
+ getNode(cur)!.random = getNode(cur!.random)
+ cur = cur!.next
+ }
+
+ return getNode(head)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1161,12 +1278,67 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a Node.
+ * public class Node {
+ * public var val: Int
+ * public var next: Node?
+ * public var random: Node?
+ * public init(_ val: Int) {
+ * self.val = val
+ * self.next = nil
+ * self.random = nil
+ * }
+ * }
+ */
+
+class Solution {
+ func copyRandomList(_ head: Node?) -> Node? {
+ if head == nil {
+ return nil
+ }
+
+ var l1 = head
+ while l1 != nil {
+ let l2 = Node(l1!.val)
+ l2.next = l1?.next
+ l1?.next = l2
+ l1 = l2.next
+ }
+
+ let newHead = head?.next
+ l1 = head
+ while l1 != nil {
+ if let random = l1?.random {
+ l1?.next?.random = random.next
+ }
+ l1 = l1?.next?.next
+ }
+
+ l1 = head
+ while l1 != nil {
+ let l2 = l1?.next
+ l1?.next = l2?.next
+ if l2?.next != nil {
+ l2?.next = l2?.next?.next
+ }
+ l1 = l1?.next
+ }
+
+ return newHead
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(n)$
-* Space complexity: $O(1)$
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(n)$ for the output.
---
@@ -1525,9 +1697,62 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a Node.
+ * public class Node {
+ * public var val: Int
+ * public var next: Node?
+ * public var random: Node?
+ * public init(_ val: Int) {
+ * self.val = val
+ * self.next = nil
+ * self.random = nil
+ * }
+ * }
+ */
+
+class Solution {
+ func copyRandomList(_ head: Node?) -> Node? {
+ if head == nil {
+ return nil
+ }
+
+ var l1 = head
+ while l1 != nil {
+ let l2 = Node(l1!.val)
+ l2.next = l1?.random
+ l1?.random = l2
+ l1 = l1?.next
+ }
+
+ let newHead = head?.random
+
+ l1 = head
+ while l1 != nil {
+ let l2 = l1?.random
+ l2?.random = l2?.next?.random
+ l1 = l1?.next
+ }
+
+ l1 = head
+ while l1 != nil {
+ let l2 = l1?.random
+ l1?.random = l2?.next
+ l2?.next = l1?.next?.random
+ l1 = l1?.next
+ }
+
+ return newHead
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(n)$
-* Space complexity: $O(1)$
\ No newline at end of file
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(n)$ for the output.
\ No newline at end of file
diff --git a/articles/count-connected-components.md b/articles/count-connected-components.md
index 0f0dc28ba..c31580864 100644
--- a/articles/count-connected-components.md
+++ b/articles/count-connected-components.md
@@ -229,6 +229,41 @@ class Solution {
}
```
+```swift
+class Solution {
+ func countComponents(_ n: Int, _ edges: [[Int]]) -> Int {
+ var adj = Array(repeating: [Int](), count: n)
+ var visit = Array(repeating: false, count: n)
+
+ for edge in edges {
+ let u = edge[0], v = edge[1]
+ adj[u].append(v)
+ adj[v].append(u)
+ }
+
+ func dfs(_ node: Int) {
+ for nei in adj[node] {
+ if !visit[nei] {
+ visit[nei] = true
+ dfs(nei)
+ }
+ }
+ }
+
+ var res = 0
+ for node in 0.. Int {
+ var adj = Array(repeating: [Int](), count: n)
+ var visit = Array(repeating: false, count: n)
+ for edge in edges {
+ let u = edge[0], v = edge[1]
+ adj[u].append(v)
+ adj[v].append(u)
+ }
+
+ func bfs(_ node: Int) {
+ var q = Deque()
+ q.append(node)
+ visit[node] = true
+ while !q.isEmpty {
+ let cur = q.removeFirst()
+ for nei in adj[cur] {
+ if !visit[nei] {
+ visit[nei] = true
+ q.append(nei)
+ }
+ }
+ }
+ }
+
+ var res = 0
+ for node in 0.. Int {
+ var cur = node
+ while cur != parent[cur] {
+ parent[cur] = parent[parent[cur]]
+ cur = parent[cur]
+ }
+ return cur
+ }
+
+ func union(_ u: Int, _ v: Int) -> Bool {
+ let pu = find(u)
+ let pv = find(v)
+ if pu == pv { return false }
+ var rootU = pu
+ var rootV = pv
+ if rank[rootV] > rank[rootU] {
+ swap(&rootU, &rootV)
+ }
+ parent[rootV] = rootU
+ rank[rootU] += rank[rootV]
+ return true
+ }
+}
+
+class Solution {
+ func countComponents(_ n: Int, _ edges: [[Int]]) -> Int {
+ let dsu = DSU(n)
+ var res = n
+ for edge in edges {
+ let u = edge[0], v = edge[1]
+ if dsu.union(u, v) {
+ res -= 1
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/count-good-nodes-in-binary-tree.md b/articles/count-good-nodes-in-binary-tree.md
index 1eda1a860..d9356f32c 100644
--- a/articles/count-good-nodes-in-binary-tree.md
+++ b/articles/count-good-nodes-in-binary-tree.md
@@ -250,6 +250,39 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func goodNodes(_ root: TreeNode?) -> Int {
+ func dfs(_ node: TreeNode?, _ maxVal: Int) -> Int {
+ guard let node = node else { return 0 }
+
+ var res = node.val >= maxVal ? 1 : 0
+ let newMaxVal = max(maxVal, node.val)
+ res += dfs(node.left, newMaxVal)
+ res += dfs(node.right, newMaxVal)
+ return res
+ }
+
+ return dfs(root, root?.val ?? Int.min)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -545,6 +578,51 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func goodNodes(_ root: TreeNode?) -> Int {
+ guard let root = root else { return 0 }
+
+ var res = 0
+ var q = Deque<(TreeNode, Int)>()
+ q.append((root, Int.min))
+
+ while !q.isEmpty {
+ let (node, maxVal) = q.popFirst()!
+ if node.val >= maxVal {
+ res += 1
+ }
+
+ let newMaxVal = max(maxVal, node.val)
+
+ if let left = node.left {
+ q.append((left, newMaxVal))
+ }
+ if let right = node.right {
+ q.append((right, newMaxVal))
+ }
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/count-number-of-islands.md b/articles/count-number-of-islands.md
index cee406700..042d79082 100644
--- a/articles/count-number-of-islands.md
+++ b/articles/count-number-of-islands.md
@@ -236,6 +236,40 @@ class Solution {
}
```
+```swift
+class Solution {
+ func numIslands(_ grid: [[Character]]) -> Int {
+ let directions = [[1, 0], [-1, 0], [0, 1], [0, -1]]
+ let ROWS = grid.count
+ let COLS = grid[0].count
+ var islands = 0
+ var grid = grid
+
+ func dfs(_ r: Int, _ c: Int) {
+ if r < 0 || c < 0 || r >= ROWS || c >= COLS || grid[r][c] == "0" {
+ return
+ }
+
+ grid[r][c] = "0"
+ for dir in directions {
+ dfs(r + dir[0], c + dir[1])
+ }
+ }
+
+ for r in 0.. Int {
+ let directions = [[1, 0], [-1, 0], [0, 1], [0, -1]]
+ let ROWS = grid.count
+ let COLS = grid[0].count
+ var islands = 0
+ var grid = grid
+
+ func bfs(_ r: Int, _ c: Int) {
+ var queue = Deque<(Int, Int)>()
+ grid[r][c] = "0"
+ queue.append((r, c))
+
+ while !queue.isEmpty {
+ let (row, col) = queue.popFirst()!
+ for dir in directions {
+ let nr = row + dir[0]
+ let nc = col + dir[1]
+ if nr < 0 || nc < 0 || nr >= ROWS || nc >= COLS || grid[nr][nc] == "0" {
+ continue
+ }
+ queue.append((nr, nc))
+ grid[nr][nc] = "0"
+ }
+ }
+ }
+
+ for r in 0.. Int {
+ if parent[node] != node {
+ parent[node] = find(parent[node])
+ }
+ return parent[node]
+ }
+
+ func union(_ u: Int, _ v: Int) -> Bool {
+ let pu = find(u)
+ let pv = find(v)
+ if pu == pv {
+ return false
+ }
+ if size[pu] >= size[pv] {
+ size[pu] += size[pv]
+ parent[pv] = pu
+ } else {
+ size[pv] += size[pu]
+ parent[pu] = pv
+ }
+ return true
+ }
+}
+
+class Solution {
+ func numIslands(_ grid: [[Character]]) -> Int {
+ let ROWS = grid.count
+ let COLS = grid[0].count
+ let dsu = DSU(ROWS * COLS)
+
+ func index(_ r: Int, _ c: Int) -> Int {
+ return r * COLS + c
+ }
+
+ let directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
+ var islands = 0
+ var grid = grid
+
+ for r in 0..= ROWS || nc >= COLS || grid[nr][nc] == "0" {
+ continue
+ }
+ if dsu.union(index(r, c), index(nr, nc)) {
+ islands -= 1
+ }
+ }
+ }
+ }
+ }
+
+ return islands
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/count-paths.md b/articles/count-paths.md
index 61ab8e148..5db166df2 100644
--- a/articles/count-paths.md
+++ b/articles/count-paths.md
@@ -121,6 +121,24 @@ class Solution {
}
```
+```swift
+class Solution {
+ func uniquePaths(_ m: Int, _ n: Int) -> Int {
+ func dfs(_ i: Int, _ j: Int) -> Int {
+ if i == m - 1 && j == n - 1 {
+ return 1
+ }
+ if i >= m || j >= n {
+ return 0
+ }
+ return dfs(i, j + 1) + dfs(i + 1, j)
+ }
+
+ return dfs(0, 0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -304,6 +322,31 @@ class Solution {
}
```
+```swift
+class Solution {
+ func uniquePaths(_ m: Int, _ n: Int) -> Int {
+ var memo = Array(repeating: Array(repeating: -1, count: n), count: m)
+
+ func dfs(_ i: Int, _ j: Int) -> Int {
+ if i == m - 1 && j == n - 1 {
+ return 1
+ }
+ if i >= m || j >= n {
+ return 0
+ }
+ if memo[i][j] != -1 {
+ return memo[i][j]
+ }
+
+ memo[i][j] = dfs(i, j + 1) + dfs(i + 1, j)
+ return memo[i][j]
+ }
+
+ return dfs(0, 0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -442,6 +485,23 @@ class Solution {
}
```
+```swift
+class Solution {
+ func uniquePaths(_ m: Int, _ n: Int) -> Int {
+ var dp = Array(repeating: Array(repeating: 0, count: n + 1), count: m + 1)
+ dp[m - 1][n - 1] = 1
+
+ for i in stride(from: m - 1, through: 0, by: -1) {
+ for j in stride(from: n - 1, through: 0, by: -1) {
+ dp[i][j] += dp[i + 1][j] + dp[i][j + 1]
+ }
+ }
+
+ return dp[0][0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -585,6 +645,23 @@ class Solution {
}
```
+```swift
+class Solution {
+ func uniquePaths(_ m: Int, _ n: Int) -> Int {
+ var row = Array(repeating: 1, count: n)
+
+ for _ in 0..<(m - 1) {
+ var newRow = Array(repeating: 1, count: n)
+ for j in stride(from: n - 2, through: 0, by: -1) {
+ newRow[j] = newRow[j + 1] + row[j]
+ }
+ row = newRow
+ }
+ return row[0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -716,6 +793,22 @@ class Solution {
}
```
+```swift
+class Solution {
+ func uniquePaths(_ m: Int, _ n: Int) -> Int {
+ var dp = Array(repeating: 1, count: n)
+
+ for _ in stride(from: m - 2, through: 0, by: -1) {
+ for j in stride(from: n - 2, through: 0, by: -1) {
+ dp[j] += dp[j + 1]
+ }
+ }
+
+ return dp[0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -896,6 +989,30 @@ class Solution {
}
```
+```swift
+class Solution {
+ func uniquePaths(_ m: Int, _ n: Int) -> Int {
+ if m == 1 || n == 1 {
+ return 1
+ }
+ var m = m, n = n
+ if m < n {
+ swap(&m, &n)
+ }
+
+ var res = 1
+ var j = 1
+ for i in m..<(m + n - 1) {
+ res *= i
+ res /= j
+ j += 1
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/count-squares.md b/articles/count-squares.md
index 6b27ebb50..1b5defe8c 100644
--- a/articles/count-squares.md
+++ b/articles/count-squares.md
@@ -240,6 +240,40 @@ class CountSquares() {
}
```
+```swift
+class CountSquares {
+ private var ptsCount: [String: Int]
+ private var pts: [[Int]]
+
+ init() {
+ self.ptsCount = [:]
+ self.pts = []
+ }
+
+ func add(_ point: [Int]) {
+ let key = "\(point[0]),\(point[1])"
+ ptsCount[key, default: 0] += 1
+ pts.append(point)
+ }
+
+ func count(_ point: [Int]) -> Int {
+ var res = 0
+ let px = point[0], py = point[1]
+
+ for pt in pts {
+ let x = pt[0], y = pt[1]
+ if abs(py - y) != abs(px - x) || x == px || y == py {
+ continue
+ }
+ let key1 = "\(x),\(py)"
+ let key2 = "\(px),\(y)"
+ res += (ptsCount[key1] ?? 0) * (ptsCount[key2] ?? 0)
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -320,10 +354,9 @@ public class CountSquares {
```cpp
class CountSquares {
unordered_map> ptsCount;
+
public:
- CountSquares() {
-
- }
+ CountSquares() {}
void add(vector point) {
ptsCount[point[0]][point[1]]++;
@@ -531,6 +564,40 @@ class CountSquares {
}
```
+```swift
+class CountSquares {
+ var ptsCount: [Int: [Int: Int]]
+
+ init() {
+ ptsCount = [:]
+ }
+
+ func add(_ point: [Int]) {
+ let x = point[0]
+ let y = point[1]
+ ptsCount[x, default: [:]][y, default: 0] += 1
+ }
+
+ func count(_ point: [Int]) -> Int {
+ var res = 0
+ let x1 = point[0]
+ let y1 = point[1]
+
+ if let yMap = ptsCount[x1] {
+ for (y2, countXY2) in yMap {
+ let side = y2 - y1
+ if side == 0 { continue }
+ let x3 = x1 + side
+ let x4 = x1 - side
+ res += countXY2 * (ptsCount[x3]?[y1] ?? 0) * (ptsCount[x3]?[y2] ?? 0)
+ res += countXY2 * (ptsCount[x4]?[y1] ?? 0) * (ptsCount[x4]?[y2] ?? 0)
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/count-subsequences.md b/articles/count-subsequences.md
index 04fd77389..241876a84 100644
--- a/articles/count-subsequences.md
+++ b/articles/count-subsequences.md
@@ -181,6 +181,29 @@ class Solution {
}
```
+```swift
+class Solution {
+ func numDistinct(_ s: String, _ t: String) -> Int {
+ let sArray = Array(s), tArray = Array(t)
+ let sLen = sArray.count, tLen = tArray.count
+ if tLen > sLen { return 0 }
+
+ func dfs(_ i: Int, _ j: Int) -> Int {
+ if j == tLen { return 1 }
+ if i == sLen { return 0 }
+
+ var res = dfs(i + 1, j)
+ if sArray[i] == tArray[j] {
+ res += dfs(i + 1, j + 1)
+ }
+ return res
+ }
+
+ return dfs(0, 0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -188,6 +211,8 @@ class Solution {
* Time complexity: $O(2 ^ m)$
* Space complexity: $O(m)$
+> Where $m$ is the length of the string $s$.
+
---
## 2. Dynamic Programming (Top-Down)
@@ -396,6 +421,33 @@ class Solution {
}
```
+```swift
+class Solution {
+ func numDistinct(_ s: String, _ t: String) -> Int {
+ let sArray = Array(s), tArray = Array(t)
+ let sLen = sArray.count, tLen = tArray.count
+ if tLen > sLen { return 0 }
+
+ var dp = [[Int]: Int]()
+
+ func dfs(_ i: Int, _ j: Int) -> Int {
+ if j == tLen { return 1 }
+ if i == sLen { return 0 }
+ if let val = dp[[i, j]] { return val }
+
+ var res = dfs(i + 1, j)
+ if sArray[i] == tArray[j] {
+ res += dfs(i + 1, j + 1)
+ }
+ dp[[i, j]] = res
+ return res
+ }
+
+ return dfs(0, 0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -458,7 +510,7 @@ class Solution {
public:
int numDistinct(string s, string t) {
int m = s.length(), n = t.length();
- vector> dp(m + 1, vector(n + 1, 0));
+ vector> dp(m + 1, vector(n + 1, 0));
for (int i = 0; i <= m; i++) {
dp[i][n] = 1;
@@ -582,6 +634,42 @@ class Solution {
}
```
+```swift
+class Solution {
+ func numDistinct(_ s: String, _ t: String) -> Int {
+ let m = s.count, n = t.count
+ var dp = Array(
+ repeating: Array(repeating: 0, count: n + 1),
+ count: m + 1
+ )
+
+ let sArray = Array(s)
+ let tArray = Array(t)
+
+ for i in 0...m {
+ dp[i][n] = 1
+ }
+
+ for i in stride(from: m - 1, through: 0, by: -1) {
+ for j in stride(from: n - 1, through: 0, by: -1) {
+ let base = dp[i + 1][j]
+ dp[i][j] = base
+ if sArray[i] == tArray[j] {
+ let addend = dp[i + 1][j + 1]
+ if base > Int.max - addend {
+ dp[i][j] = 0
+ } else {
+ dp[i][j] += addend
+ }
+ }
+ }
+ }
+
+ return dp[0][0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -643,8 +731,8 @@ class Solution {
public:
int numDistinct(string s, string t) {
int m = s.size(), n = t.size();
- vector dp(n + 1, 0);
- vector nextDp(n + 1, 0);
+ vector dp(n + 1, 0);
+ vector nextDp(n + 1, 0);
dp[n] = nextDp[n] = 1;
for (int i = m - 1; i >= 0; i--) {
@@ -762,6 +850,38 @@ class Solution {
}
```
+```swift
+class Solution {
+ func numDistinct(_ s: String, _ t: String) -> Int {
+ let m = s.count, n = t.count
+ var dp = [Int](repeating: 0, count: n + 1)
+ var nextDp = [Int](repeating: 0, count: n + 1)
+ dp[n] = 1
+ nextDp[n] = 1
+
+ let sArr = Array(s)
+ let tArr = Array(t)
+
+ for i in stride(from: m - 1, through: 0, by: -1) {
+ for j in stride(from: n - 1, through: 0, by: -1) {
+ nextDp[j] = dp[j]
+ if sArr[i] == tArr[j] {
+ let addend = dp[j + 1]
+ if nextDp[j] > Int.max - addend {
+ nextDp[j] = 0
+ } else {
+ nextDp[j] += addend
+ }
+ }
+ }
+ dp = nextDp
+ }
+
+ return dp[0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -827,13 +947,13 @@ class Solution {
public:
int numDistinct(string s, string t) {
int m = s.size(), n = t.size();
- vector dp(n + 1, 0);
+ vector dp(n + 1, 0);
dp[n] = 1;
for (int i = m - 1; i >= 0; i--) {
int prev = 1;
for (int j = n - 1; j >= 0; j--) {
- int res = dp[j];
+ uint res = dp[j];
if (s[i] == t[j]) {
res += prev;
}
@@ -950,6 +1070,37 @@ class Solution {
}
```
+```swift
+class Solution {
+ func numDistinct(_ s: String, _ t: String) -> Int {
+ let m = s.count, n = t.count
+ var dp = [Int](repeating: 0, count: n + 1)
+ dp[n] = 1
+ let sArr = Array(s)
+ let tArr = Array(t)
+
+ for i in stride(from: m - 1, through: 0, by: -1) {
+ var prev = 1
+ for j in stride(from: n - 1, through: 0, by: -1) {
+ let base = dp[j]
+ var res = base
+ if sArr[i] == tArr[j] {
+ if base > Int.max - prev {
+ res = 0
+ } else {
+ res += prev
+ }
+ }
+ prev = dp[j]
+ dp[j] = res
+ }
+ }
+
+ return dp[0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/counting-bits.md b/articles/counting-bits.md
index ac8139aba..66b5db885 100644
--- a/articles/counting-bits.md
+++ b/articles/counting-bits.md
@@ -120,6 +120,24 @@ class Solution {
}
```
+```swift
+class Solution {
+ func countBits(_ n: Int) -> [Int] {
+ var res = [Int]()
+ for num in 0...n {
+ var one = 0
+ for i in 0..<32 {
+ if num & (1 << i) != 0 {
+ one += 1
+ }
+ }
+ res.append(one)
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -246,6 +264,22 @@ class Solution {
}
```
+```swift
+class Solution {
+ func countBits(_ n: Int) -> [Int] {
+ var res = [Int](repeating: 0, count: n + 1)
+ for i in 1..<(n + 1) {
+ var num = i
+ while num != 0 {
+ res[i] += 1
+ num &= (num - 1)
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -338,6 +372,18 @@ class Solution {
}
```
+```swift
+class Solution {
+ func countBits(_ n: Int) -> [Int] {
+ var res = [Int](repeating: 0, count: n + 1)
+ for num in 1..<(n + 1) {
+ res[num] = num.nonzeroBitCount
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -471,6 +517,23 @@ class Solution {
}
```
+```swift
+class Solution {
+ func countBits(_ n: Int) -> [Int] {
+ var dp = [Int](repeating: 0, count: n + 1)
+ var offset = 1
+
+ for i in 1..<(n + 1) {
+ if offset * 2 == i {
+ offset = i
+ }
+ dp[i] = 1 + dp[i - offset]
+ }
+ return dp
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -570,6 +633,18 @@ class Solution {
}
```
+```swift
+class Solution {
+ func countBits(_ n: Int) -> [Int] {
+ var dp = [Int](repeating: 0, count: n + 1)
+ for i in 0..<(n + 1) {
+ dp[i] = dp[i >> 1] + (i & 1)
+ }
+ return dp
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/course-schedule-ii.md b/articles/course-schedule-ii.md
index 7980e9e5e..6a3e85924 100644
--- a/articles/course-schedule-ii.md
+++ b/articles/course-schedule-ii.md
@@ -329,6 +329,51 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findOrder(_ numCourses: Int, _ prerequisites: [[Int]]) -> [Int] {
+ var prereq = [Int: [Int]]()
+ for c in 0..()
+ var cycle = Set()
+
+ func dfs(_ crs: Int) -> Bool {
+ if cycle.contains(crs) {
+ return false
+ }
+ if visit.contains(crs) {
+ return true
+ }
+
+ cycle.insert(crs)
+ for pre in prereq[crs]! {
+ if !dfs(pre) {
+ return false
+ }
+ }
+ cycle.remove(crs)
+ visit.insert(crs)
+ output.append(crs)
+ return true
+ }
+
+ for c in 0.. [Int] {
+ var indegree = Array(repeating: 0, count: numCourses)
+ var adj = Array(repeating: [Int](), count: numCourses)
+
+ for pair in prerequisites {
+ let src = pair[0]
+ let dst = pair[1]
+ indegree[dst] += 1
+ adj[src].append(dst)
+ }
+
+ var queue = Deque()
+ for n in 0.. [Int] {
+ var adj = Array(repeating: [Int](), count: numCourses)
+ var indegree = Array(repeating: 0, count: numCourses)
+
+ for pair in prerequisites {
+ let nxt = pair[0]
+ let pre = pair[1]
+ indegree[nxt] += 1
+ adj[pre].append(nxt)
+ }
+
+ var output = [Int]()
+
+ func dfs(_ node: Int) {
+ output.append(node)
+ indegree[node] -= 1
+ for nei in adj[node] {
+ indegree[nei] -= 1
+ if indegree[nei] == 0 {
+ dfs(nei)
+ }
+ }
+ }
+
+ for i in 0.. Bool {
+ // Map each course to its prerequisites
+ var preMap = [Int: [Int]]()
+ for i in 0..()
+
+ func dfs(_ crs: Int) -> Bool {
+ if visiting.contains(crs) {
+ // Cycle detected
+ return false
+ }
+ if preMap[crs]!.isEmpty {
+ return true
+ }
+
+ visiting.insert(crs)
+ for pre in preMap[crs]! {
+ if !dfs(pre) {
+ return false
+ }
+ }
+ visiting.remove(crs)
+ preMap[crs] = []
+ return true
+ }
+
+ for c in 0.. Bool {
+ var indegree = Array(repeating: 0, count: numCourses)
+ var adj = Array(repeating: [Int](), count: numCourses)
+
+ for pair in prerequisites {
+ let src = pair[0]
+ let dst = pair[1]
+ indegree[dst] += 1
+ adj[src].append(dst)
+ }
+
+ var queue = Deque()
+ for n in 0.. [Int] {
+ let n = temperatures.count
+ var res = [Int]()
+
+ for i in 0.. temperatures[i] {
+ break
+ }
+ j += 1
+ count += 1
+ }
+ count = (j == n) ? 0 : count
+ res.append(count)
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(n ^ 2)$
-* Space complexity: $O(1)$
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(n)$ space for the output array.
---
@@ -323,6 +349,24 @@ class Solution {
}
```
+```swift
+class Solution {
+ func dailyTemperatures(_ temperatures: [Int]) -> [Int] {
+ var res = [Int](repeating: 0, count: temperatures.count)
+ var stack = [(Int, Int)]() // Pair: (temperature, index)
+
+ for (i, t) in temperatures.enumerated() {
+ while !stack.isEmpty && t > stack.last!.0 {
+ let (stackT, stackInd) = stack.removeLast()
+ res[stackInd] = i - stackInd
+ }
+ stack.append((t, i))
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -508,9 +552,36 @@ class Solution {
}
```
+```swift
+class Solution {
+ func dailyTemperatures(_ temperatures: [Int]) -> [Int] {
+ let n = temperatures.count
+ var res = [Int](repeating: 0, count: n)
+
+ for i in stride(from: n - 2, through: 0, by: -1) {
+ var j = i + 1
+ while j < n && temperatures[j] <= temperatures[i] {
+ if res[j] == 0 {
+ j = n
+ break
+ }
+ j += res[j]
+ }
+
+ if j < n {
+ res[i] = j - i
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(n)$
-* Space complexity: $O(1)$
\ No newline at end of file
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(n)$ space for the output array.
\ No newline at end of file
diff --git a/articles/decode-ways.md b/articles/decode-ways.md
index bfda19321..c735d1d3f 100644
--- a/articles/decode-ways.md
+++ b/articles/decode-ways.md
@@ -163,6 +163,34 @@ class Solution {
}
```
+```swift
+class Solution {
+ func numDecodings(_ s: String) -> Int {
+ let chars = Array(s)
+
+ func dfs(_ i: Int) -> Int {
+ if i == chars.count {
+ return 1
+ }
+ if chars[i] == "0" {
+ return 0
+ }
+
+ var res = dfs(i + 1)
+ if i < chars.count - 1 {
+ if chars[i] == "1" || (chars[i] == "2" && chars[i + 1] < "7") {
+ res += dfs(i + 2)
+ }
+ }
+
+ return res
+ }
+
+ return dfs(0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -375,6 +403,35 @@ class Solution {
}
```
+```swift
+class Solution {
+ func numDecodings(_ s: String) -> Int {
+ let chars = Array(s)
+ var dp = [Int: Int]()
+ dp[chars.count] = 1
+
+ func dfs(_ i: Int) -> Int {
+ if let cached = dp[i] {
+ return cached
+ }
+ if chars[i] == "0" {
+ return 0
+ }
+
+ var res = dfs(i + 1)
+ if i + 1 < chars.count,
+ chars[i] == "1" || (chars[i] == "2" && "0123456".contains(chars[i + 1])) {
+ res += dfs(i + 2)
+ }
+ dp[i] = res
+ return res
+ }
+
+ return dfs(0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -533,6 +590,30 @@ class Solution {
}
```
+```swift
+class Solution {
+ func numDecodings(_ s: String) -> Int {
+ let chars = Array(s)
+ var dp = [Int: Int]()
+ dp[chars.count] = 1
+
+ for i in stride(from: chars.count - 1, through: 0, by: -1) {
+ if chars[i] == "0" {
+ dp[i] = 0
+ } else {
+ dp[i] = dp[i + 1] ?? 0
+ }
+
+ if i + 1 < chars.count,
+ chars[i] == "1" || (chars[i] == "2" && "0123456".contains(chars[i + 1])) {
+ dp[i]! += dp[i + 2] ?? 0
+ }
+ }
+ return dp[0] ?? 0
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -711,6 +792,30 @@ class Solution {
}
```
+```swift
+class Solution {
+ func numDecodings(_ s: String) -> Int {
+ let chars = Array(s)
+ var dp = 0, dp1 = 1, dp2 = 0
+
+ for i in stride(from: chars.count - 1, through: 0, by: -1) {
+ if chars[i] == "0" {
+ dp = 0
+ } else {
+ dp = dp1
+ }
+
+ if i + 1 < chars.count,
+ chars[i] == "1" || (chars[i] == "2" && "0123456".contains(chars[i + 1])) {
+ dp += dp2
+ }
+ (dp, dp1, dp2) = (0, dp, dp1)
+ }
+ return dp1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/depth-of-binary-tree.md b/articles/depth-of-binary-tree.md
index efd76b64d..88a35751d 100644
--- a/articles/depth-of-binary-tree.md
+++ b/articles/depth-of-binary-tree.md
@@ -171,6 +171,30 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func maxDepth(_ root: TreeNode?) -> Int {
+ guard let root = root else { return 0 }
+ return 1 + max(maxDepth(root.left), maxDepth(root.right))
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -440,6 +464,41 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func maxDepth(_ root: TreeNode?) -> Int {
+ var stack: [(TreeNode?, Int)] = [(root, 1)]
+ var res = 0
+
+ while !stack.isEmpty {
+ let (node, depth) = stack.removeLast()
+
+ if let node = node {
+ res = max(res, depth)
+ stack.append((node.left, depth + 1))
+ stack.append((node.right, depth + 1))
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -723,6 +782,47 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func maxDepth(_ root: TreeNode?) -> Int {
+ var queue = Deque()
+ if let root = root {
+ queue.append(root)
+ }
+
+ var level = 0
+ while !queue.isEmpty {
+ for _ in 0..]
+ private var tweetMap: [Int: [(Int, Int)]]
+
+ init() {
+ self.time = 0
+ self.followMap = [:]
+ self.tweetMap = [:]
+ }
+
+ func postTweet(_ userId: Int, _ tweetId: Int) {
+ if tweetMap[userId] == nil {
+ tweetMap[userId] = []
+ }
+ tweetMap[userId]!.append((time, tweetId))
+ time += 1
+ }
+
+ func getNewsFeed(_ userId: Int) -> [Int] {
+ var feed = tweetMap[userId] ?? []
+ if let followees = followMap[userId] {
+ for followeeId in followees {
+ if let tweets = tweetMap[followeeId] {
+ feed.append(contentsOf: tweets)
+ }
+ }
+ }
+ feed.sort { $0.0 > $1.0 }
+ return feed.prefix(10).map { $0.1 }
+ }
+
+ func follow(_ followerId: Int, _ followeeId: Int) {
+ if followerId != followeeId {
+ followMap[followerId, default: Set()].insert(followeeId)
+ }
+ }
+
+ func unfollow(_ followerId: Int, _ followeeId: Int) {
+ followMap[followerId]?.remove(followeeId)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -769,6 +814,84 @@ class Twitter {
}
```
+```swift
+class Twitter {
+ private var count: Int
+ private var tweetMap: [Int: [(Int, Int)]] // userId -> list of (count, tweetId)
+ private var followMap: [Int: Set] // userId -> set of followeeId
+
+ init() {
+ self.count = 0
+ self.tweetMap = [:]
+ self.followMap = [:]
+ }
+
+ func postTweet(_ userId: Int, _ tweetId: Int) {
+ tweetMap[userId, default: []].append((count, tweetId))
+ count -= 1
+ }
+
+ func getNewsFeed(_ userId: Int) -> [Int] {
+ var res = [Int]()
+ var minHeap = Heap
- ()
+
+ followMap[userId, default: Set()].insert(userId)
+ if let followees = followMap[userId] {
+ for followee in followees {
+ if let tweets = tweetMap[followee], !tweets.isEmpty {
+ let index = tweets.count - 1
+ let (cnt, tweetId) = tweets[index]
+ minHeap.insert(
+ Item(
+ count: cnt, tweetId: tweetId,
+ followeeId: followee, index: index - 1
+ )
+ )
+ }
+ }
+ }
+
+ while !minHeap.isEmpty && res.count < 10 {
+ let entry = minHeap.popMin()!
+ res.append(entry.tweetId)
+ if entry.index >= 0, let tweets = tweetMap[entry.followeeId] {
+ let (cnt, tweetId) = tweets[entry.index]
+ minHeap.insert(
+ Item(
+ count: cnt, tweetId: tweetId,
+ followeeId: entry.followeeId, index: entry.index - 1
+ )
+ )
+ }
+ }
+ return res
+ }
+
+ func follow(_ followerId: Int, _ followeeId: Int) {
+ followMap[followerId, default: Set()].insert(followeeId)
+ }
+
+ func unfollow(_ followerId: Int, _ followeeId: Int) {
+ followMap[followerId]?.remove(followeeId)
+ }
+}
+
+struct Item: Comparable {
+ let count: Int
+ let tweetId: Int
+ let followeeId: Int
+ let index: Int
+
+ static func < (lhs: Item, rhs: Item) -> Bool {
+ return lhs.count < rhs.count
+ }
+
+ static func == (lhs: Item, rhs: Item) -> Bool {
+ return lhs.count == rhs.count
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1425,6 +1548,112 @@ class Twitter {
}
```
+```swift
+struct Item: Comparable {
+ let count: Int
+ let tweetId: Int
+ let followeeId: Int
+ let index: Int
+
+ static func < (lhs: Item, rhs: Item) -> Bool {
+ return lhs.count < rhs.count
+ }
+
+ static func == (lhs: Item, rhs: Item) -> Bool {
+ return lhs.count == rhs.count &&
+ lhs.tweetId == rhs.tweetId &&
+ lhs.followeeId == rhs.followeeId &&
+ lhs.index == rhs.index
+ }
+}
+
+class Twitter {
+ private var count: Int
+ private var tweetMap: [Int: [(Int, Int)]] // userId -> list of (count, tweetId)
+ private var followMap: [Int: Set] // userId -> set of followeeId
+
+ init() {
+ self.count = 0
+ self.tweetMap = [:]
+ self.followMap = [:]
+ }
+
+ func postTweet(_ userId: Int, _ tweetId: Int) {
+ tweetMap[userId, default: []].append((count, tweetId))
+ if tweetMap[userId]!.count > 10 {
+ tweetMap[userId]!.removeFirst()
+ }
+ count -= 1
+ }
+
+ func getNewsFeed(_ userId: Int) -> [Int] {
+ var res = [Int]()
+ var minHeap = Heap
- ()
+ followMap[userId, default: Set()].insert(userId)
+
+ if followMap[userId]!.count >= 10 {
+ var maxHeap = Heap
- ()
+ for followeeId in followMap[userId]! {
+ if let tweets = tweetMap[followeeId], !tweets.isEmpty {
+ let index = tweets.count - 1
+ let (cnt, tweetId) = tweets[index]
+ maxHeap.insert(
+ Item(
+ count: cnt, tweetId: tweetId,
+ followeeId: followeeId, index: index - 1
+ )
+ )
+ if maxHeap.count > 10 {
+ maxHeap.removeMax()
+ }
+ }
+ }
+ while !maxHeap.isEmpty {
+ let item = maxHeap.popMax()!
+ minHeap.insert(item)
+ }
+ } else {
+ for followeeId in followMap[userId]! {
+ if let tweets = tweetMap[followeeId], !tweets.isEmpty {
+ let index = tweets.count - 1
+ let (cnt, tweetId) = tweets[index]
+ minHeap.insert(
+ Item(
+ count: cnt, tweetId: tweetId,
+ followeeId: followeeId, index: index - 1
+ )
+ )
+ }
+ }
+ }
+
+ while !minHeap.isEmpty && res.count < 10 {
+ let item = minHeap.popMin()!
+ res.append(item.tweetId)
+ if item.index >= 0, let tweets = tweetMap[item.followeeId] {
+ let (cnt, tweetId) = tweets[item.index]
+ minHeap.insert(
+ Item(
+ count: cnt, tweetId: tweetId,
+ followeeId: item.followeeId, index: item.index - 1
+ )
+ )
+ }
+ }
+
+ return res
+ }
+
+ func follow(_ followerId: Int, _ followeeId: Int) {
+ followMap[followerId, default: Set()].insert(followeeId)
+ }
+
+ func unfollow(_ followerId: Int, _ followeeId: Int) {
+ followMap[followerId]?.remove(followeeId)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/design-word-search-data-structure.md b/articles/design-word-search-data-structure.md
index 501e42785..033096234 100644
--- a/articles/design-word-search-data-structure.md
+++ b/articles/design-word-search-data-structure.md
@@ -222,6 +222,42 @@ class WordDictionary {
}
```
+```swift
+class WordDictionary {
+ private var store: [String]
+
+ init() {
+ self.store = []
+ }
+
+ func addWord(_ word: String) {
+ store.append(word)
+ }
+
+ func search(_ word: String) -> Bool {
+ for w in store {
+ if w.count != word.count {
+ continue
+ }
+ var i = 0
+ let wArray = Array(w)
+ let wordArray = Array(word)
+ while i < wArray.count {
+ if wArray[i] == wordArray[i] || wordArray[i] == "." {
+ i += 1
+ } else {
+ break
+ }
+ }
+ if i == wArray.count {
+ return true
+ }
+ }
+ return false
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -627,6 +663,64 @@ class WordDictionary {
}
```
+```swift
+class TrieNode {
+ var children: [Character: TrieNode]
+ var word: Bool
+
+ init() {
+ self.children = [:]
+ self.word = false
+ }
+}
+
+class WordDictionary {
+ private let root: TrieNode
+
+ init() {
+ self.root = TrieNode()
+ }
+
+ func addWord(_ word: String) {
+ var cur = root
+ for c in word {
+ if cur.children[c] == nil {
+ cur.children[c] = TrieNode()
+ }
+ cur = cur.children[c]!
+ }
+ cur.word = true
+ }
+
+ func search(_ word: String) -> Bool {
+ func dfs(_ j: Int, _ root: TrieNode) -> Bool {
+ var cur = root
+ let wordArray = Array(word)
+
+ for i in j.. Bool {
+ for i in 0.. Bool {
+ var nums = nums.sorted()
+ for i in 1.. Bool {
+ var seen = Set()
+ for num in nums {
+ if seen.contains(num) {
+ return true
+ }
+ seen.insert(num)
+ }
+ return false
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -406,6 +450,14 @@ class Solution {
}
```
+```swift
+class Solution {
+ func hasDuplicate(_ nums: [Int]) -> Bool {
+ return Set(nums).count < nums.count
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/eating-bananas.md b/articles/eating-bananas.md
index bf00f6c04..4acd82fb0 100644
--- a/articles/eating-bananas.md
+++ b/articles/eating-bananas.md
@@ -137,6 +137,27 @@ class Solution {
}
```
+```swift
+class Solution {
+ func minEatingSpeed(_ piles: [Int], _ h: Int) -> Int {
+ var speed = 1
+
+ while true {
+ var totalTime = 0
+ for pile in piles {
+ totalTime += Int(ceil(Double(pile) / Double(speed)))
+ }
+
+ if totalTime <= h {
+ return speed
+ }
+ speed += 1
+ }
+ return speed
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -338,6 +359,32 @@ class Solution {
}
```
+```swift
+class Solution {
+ func minEatingSpeed(_ piles: [Int], _ h: Int) -> Int {
+ var l = 1, r = piles.max()!
+ var res = r
+
+ while l <= r {
+ let k = (l + r) / 2
+
+ var totalTime = 0
+ for p in piles {
+ totalTime += Int(ceil(Double(p) / Double(k)))
+ }
+
+ if totalTime <= h {
+ res = k
+ r = k - 1
+ } else {
+ l = k + 1
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/edit-distance.md b/articles/edit-distance.md
index a116df5c7..7c4b6bfeb 100644
--- a/articles/edit-distance.md
+++ b/articles/edit-distance.md
@@ -169,6 +169,27 @@ class Solution {
}
```
+```swift
+class Solution {
+ func minDistance(_ word1: String, _ word2: String) -> Int {
+ let m = word1.count, n = word2.count
+ let word1Array = Array(word1), word2Array = Array(word2)
+
+ func dfs(_ i: Int, _ j: Int) -> Int {
+ if i == m { return n - j }
+ if j == n { return m - i }
+ if word1Array[i] == word2Array[j] {
+ return dfs(i + 1, j + 1)
+ }
+ let res = min(dfs(i + 1, j), dfs(i, j + 1))
+ return min(res, dfs(i + 1, j + 1)) + 1
+ }
+
+ return dfs(0, 0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -403,6 +424,32 @@ class Solution {
}
```
+```swift
+class Solution {
+ func minDistance(_ word1: String, _ word2: String) -> Int {
+ let m = word1.count, n = word2.count
+ let word1Array = Array(word1), word2Array = Array(word2)
+ var dp = [[Int?]](repeating: [Int?](repeating: nil, count: n + 1), count: m + 1)
+
+ func dfs(_ i: Int, _ j: Int) -> Int {
+ if i == m { return n - j }
+ if j == n { return m - i }
+ if let val = dp[i][j] { return val }
+
+ if word1Array[i] == word2Array[j] {
+ dp[i][j] = dfs(i + 1, j + 1)
+ } else {
+ let res = min(dfs(i + 1, j), dfs(i, j + 1), dfs(i + 1, j + 1)) + 1
+ dp[i][j] = res
+ }
+ return dp[i][j]!
+ }
+
+ return dfs(0, 0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -624,6 +671,34 @@ class Solution {
}
```
+```swift
+class Solution {
+ func minDistance(_ word1: String, _ word2: String) -> Int {
+ let m = word1.count, n = word2.count
+ let word1Array = Array(word1), word2Array = Array(word2)
+ var dp = [[Int]](repeating: [Int](repeating: Int.max, count: n + 1), count: m + 1)
+
+ for j in 0...n {
+ dp[m][j] = n - j
+ }
+ for i in 0...m {
+ dp[i][n] = m - i
+ }
+
+ for i in stride(from: m - 1, through: 0, by: -1) {
+ for j in stride(from: n - 1, through: 0, by: -1) {
+ if word1Array[i] == word2Array[j] {
+ dp[i][j] = dp[i + 1][j + 1]
+ } else {
+ dp[i][j] = 1 + min(dp[i + 1][j], dp[i][j + 1], dp[i + 1][j + 1])
+ }
+ }
+ }
+ return dp[0][0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -890,6 +965,41 @@ class Solution {
}
```
+```swift
+class Solution {
+ func minDistance(_ word1: String, _ word2: String) -> Int {
+ var m = word1.count, n = word2.count
+ var word1Array = Array(word1), word2Array = Array(word2)
+
+ if m < n {
+ swap(&m, &n)
+ swap(&word1Array, &word2Array)
+ }
+
+ var dp = [Int](repeating: 0, count: n + 1)
+ var nextDp = [Int](repeating: 0, count: n + 1)
+
+ for j in 0...n {
+ dp[j] = n - j
+ }
+
+ for i in stride(from: m - 1, through: 0, by: -1) {
+ nextDp[n] = m - i
+ for j in stride(from: n - 1, through: 0, by: -1) {
+ if word1Array[i] == word2Array[j] {
+ nextDp[j] = dp[j + 1]
+ } else {
+ nextDp[j] = 1 + min(dp[j], nextDp[j + 1], dp[j + 1])
+ }
+ }
+ dp = nextDp
+ }
+
+ return dp[0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1134,6 +1244,37 @@ class Solution {
}
```
+```swift
+class Solution {
+ func minDistance(_ word1: String, _ word2: String) -> Int {
+ var m = word1.count, n = word2.count
+ var word1Array = Array(word1), word2Array = Array(word2)
+
+ if m < n {
+ swap(&m, &n)
+ swap(&word1Array, &word2Array)
+ }
+
+ var dp = (0...n).map { n - $0 }
+
+ for i in stride(from: m - 1, through: 0, by: -1) {
+ var nextDp = dp[n]
+ dp[n] = m - i
+ for j in stride(from: n - 1, through: 0, by: -1) {
+ let temp = dp[j]
+ if word1Array[i] == word2Array[j] {
+ dp[j] = nextDp
+ } else {
+ dp[j] = 1 + min(dp[j], dp[j + 1], nextDp)
+ }
+ nextDp = temp
+ }
+ }
+ return dp[0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/evaluate-reverse-polish-notation.md b/articles/evaluate-reverse-polish-notation.md
index 9c3520b02..3ad96eff8 100644
--- a/articles/evaluate-reverse-polish-notation.md
+++ b/articles/evaluate-reverse-polish-notation.md
@@ -216,6 +216,39 @@ class Solution {
}
```
+```swift
+class Solution {
+ func evalRPN(_ tokens: [String]) -> Int {
+ var tokens = tokens
+
+ while tokens.count > 1 {
+ for i in 0.. Int {
+ var head: DoublyLinkedList? = DoublyLinkedList(val: tokens[0])
+ var curr = head
+
+ for i in 1.. Int {
+ var tokens = tokens
+
+ func dfs() -> Int {
+ let token = tokens.removeLast()
+ if let num = Int(token) {
+ return num
+ }
+
+ let right = dfs()
+ let left = dfs()
+
+ switch token {
+ case "+": return left + right
+ case "-": return left - right
+ case "*": return left * right
+ case "/": return left / right
+ default: return 0
+ }
+ }
+
+ return dfs()
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1042,6 +1161,34 @@ class Solution {
}
```
+```swift
+class Solution {
+ func evalRPN(_ tokens: [String]) -> Int {
+ var stack = [Int]()
+
+ for c in tokens {
+ switch c {
+ case "+":
+ stack.append(stack.removeLast() + stack.removeLast())
+ case "-":
+ let a = stack.removeLast()
+ let b = stack.removeLast()
+ stack.append(b - a)
+ case "*":
+ stack.append(stack.removeLast() * stack.removeLast())
+ case "/":
+ let a = stack.removeLast()
+ let b = stack.removeLast()
+ stack.append(b / a)
+ default:
+ stack.append(Int(c)!)
+ }
+ }
+ return stack[0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/find-duplicate-integer.md b/articles/find-duplicate-integer.md
index 46542d9b6..ef3317436 100644
--- a/articles/find-duplicate-integer.md
+++ b/articles/find-duplicate-integer.md
@@ -99,6 +99,20 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findDuplicate(_ nums: [Int]) -> Int {
+ var nums = nums.sorted()
+ for i in 0.. Int {
+ var seen = Set()
+ for num in nums {
+ if seen.contains(num) {
+ return num
+ }
+ seen.insert(num)
+ }
+ return -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -333,6 +362,21 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findDuplicate(_ nums: [Int]) -> Int {
+ var seen = [Int](repeating: 0, count: nums.count)
+ for num in nums {
+ if seen[num - 1] == 1 {
+ return num
+ }
+ seen[num - 1] = 1
+ }
+ return -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -457,6 +501,22 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findDuplicate(_ nums: [Int]) -> Int {
+ var nums = nums
+ for num in nums {
+ let idx = abs(num) - 1
+ if nums[idx] < 0 {
+ return abs(num)
+ }
+ nums[idx] *= -1
+ }
+ return -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -656,6 +716,27 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findDuplicate(_ nums: [Int]) -> Int {
+ let n = nums.count
+ var low = 1, high = n - 1
+
+ while low < high {
+ let mid = low + (high - low) / 2
+ let lessOrEqual = nums.filter { $0 <= mid }.count
+
+ if lessOrEqual <= mid {
+ low = mid + 1
+ } else {
+ high = mid
+ }
+ }
+ return low
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -866,6 +947,37 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findDuplicate(_ nums: [Int]) -> Int {
+ let n = nums.count
+ var res = 0
+
+ for b in 0..<32 {
+ var x = 0, y = 0
+ let mask = 1 << b
+
+ for num in nums {
+ if num & mask != 0 {
+ x += 1
+ }
+ }
+
+ for num in 1.. y {
+ res |= mask
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1052,6 +1164,31 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findDuplicate(_ nums: [Int]) -> Int {
+ var slow = 0, fast = 0
+
+ while true {
+ slow = nums[slow]
+ fast = nums[nums[fast]]
+ if slow == fast {
+ break
+ }
+ }
+
+ var slow2 = 0
+ while true {
+ slow = nums[slow]
+ slow2 = nums[slow2]
+ if slow == slow2 {
+ return slow
+ }
+ }
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/find-median-in-a-data-stream.md b/articles/find-median-in-a-data-stream.md
index ab246b370..ad27aa749 100644
--- a/articles/find-median-in-a-data-stream.md
+++ b/articles/find-median-in-a-data-stream.md
@@ -162,6 +162,30 @@ class MedianFinder() {
}
```
+```swift
+class MedianFinder {
+ private var data: [Int]
+
+ init() {
+ self.data = []
+ }
+
+ func addNum(_ num: Int) {
+ data.append(num)
+ }
+
+ func findMedian() -> Double {
+ data.sort()
+ let n = data.count
+ if n % 2 == 1 {
+ return Double(data[n / 2])
+ } else {
+ return (Double(data[n / 2]) + Double(data[n / 2 - 1])) / 2.0
+ }
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -447,6 +471,47 @@ class MedianFinder() {
}
```
+```swift
+class MedianFinder {
+ // two heaps, large, small, minheap, maxheap
+ // heaps should be equal size
+ private var small: Heap
+ private var large: Heap
+
+ init() {
+ self.small = Heap()
+ self.large = Heap()
+ }
+
+ func addNum(_ num: Int) {
+ if let top = large.min, num > top {
+ large.insert(num)
+ } else {
+ small.insert(num)
+ }
+ if small.count > large.count + 1 {
+ if let val = small.popMax() {
+ large.insert(val)
+ }
+ }
+ if large.count > small.count + 1 {
+ if let val = large.popMin() {
+ small.insert(val)
+ }
+ }
+ }
+
+ func findMedian() -> Double {
+ if small.count > large.count {
+ return Double(small.max!)
+ } else if large.count > small.count {
+ return Double(large.min!)
+ }
+ return (Double(small.max!) + Double(large.min!)) / 2.0
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/find-minimum-in-rotated-sorted-array.md b/articles/find-minimum-in-rotated-sorted-array.md
index 3c4c59be9..9443959d2 100644
--- a/articles/find-minimum-in-rotated-sorted-array.md
+++ b/articles/find-minimum-in-rotated-sorted-array.md
@@ -65,6 +65,14 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findMin(_ nums: [Int]) -> Int {
+ return nums.min()!
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -261,6 +269,32 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findMin(_ nums: [Int]) -> Int {
+ var res = nums[0]
+ var l = 0, r = nums.count - 1
+
+ while l <= r {
+ if nums[l] < nums[r] {
+ res = min(res, nums[l])
+ break
+ }
+
+ let m = (l + r) / 2
+ res = min(res, nums[m])
+
+ if nums[m] >= nums[l] {
+ l = m + 1
+ } else {
+ r = m - 1
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -396,6 +430,23 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findMin(_ nums: [Int]) -> Int {
+ var l = 0, r = nums.count - 1
+ while l < r {
+ let m = l + (r - l) / 2
+ if nums[m] < nums[r] {
+ r = m
+ } else {
+ l = m + 1
+ }
+ }
+ return nums[l]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/find-target-in-rotated-sorted-array.md b/articles/find-target-in-rotated-sorted-array.md
index 2e6dd37e5..b406838bb 100644
--- a/articles/find-target-in-rotated-sorted-array.md
+++ b/articles/find-target-in-rotated-sorted-array.md
@@ -93,6 +93,19 @@ class Solution {
}
```
+```swift
+class Solution {
+ func search(_ nums: [Int], _ target: Int) -> Int {
+ for i in 0.. Int {
+ var l = 0, r = nums.count - 1
+
+ while l < r {
+ let m = (l + r) / 2
+ if nums[m] > nums[r] {
+ l = m + 1
+ } else {
+ r = m
+ }
+ }
+
+ let pivot = l
+
+ func binarySearch(_ left: Int, _ right: Int) -> Int {
+ var l = left, r = right
+ while l <= r {
+ let mid = (l + r) / 2
+ if nums[mid] == target {
+ return mid
+ } else if nums[mid] < target {
+ l = mid + 1
+ } else {
+ r = mid - 1
+ }
+ }
+ return -1
+ }
+
+ let result = binarySearch(0, pivot - 1)
+ if result != -1 {
+ return result
+ }
+
+ return binarySearch(pivot, nums.count - 1)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -681,6 +735,46 @@ class Solution {
}
```
+```swift
+class Solution {
+ func search(_ nums: [Int], _ target: Int) -> Int {
+ var l = 0, r = nums.count - 1
+
+ while l < r {
+ let m = (l + r) / 2
+ if nums[m] > nums[r] {
+ l = m + 1
+ } else {
+ r = m
+ }
+ }
+
+ let pivot = l
+ l = 0
+ r = nums.count - 1
+
+ if target >= nums[pivot] && target <= nums[r] {
+ l = pivot
+ } else {
+ r = pivot - 1
+ }
+
+ while l <= r {
+ let m = (l + r) / 2
+ if nums[m] == target {
+ return m
+ } else if nums[m] < target {
+ l = m + 1
+ } else {
+ r = m - 1
+ }
+ }
+
+ return -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -908,6 +1002,36 @@ class Solution {
}
```
+```swift
+class Solution {
+ func search(_ nums: [Int], _ target: Int) -> Int {
+ var l = 0, r = nums.count - 1
+
+ while l <= r {
+ let mid = (l + r) / 2
+ if target == nums[mid] {
+ return mid
+ }
+
+ if nums[l] <= nums[mid] {
+ if target > nums[mid] || target < nums[l] {
+ l = mid + 1
+ } else {
+ r = mid - 1
+ }
+ } else {
+ if target < nums[mid] || target > nums[r] {
+ r = mid - 1
+ } else {
+ l = mid + 1
+ }
+ }
+ }
+ return -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/foreign-dictionary.md b/articles/foreign-dictionary.md
index f1353b74a..1bb32e486 100644
--- a/articles/foreign-dictionary.md
+++ b/articles/foreign-dictionary.md
@@ -405,6 +405,65 @@ class Solution {
}
```
+```swift
+class Solution {
+ func foreignDictionary(_ words: [String]) -> String {
+ var adj = [Character: Set]()
+ for word in words {
+ for char in word {
+ if adj[char] == nil {
+ adj[char] = Set()
+ }
+ }
+ }
+
+ for i in 0.. w2.count && String(w1.prefix(minLen)) == String(w2.prefix(minLen)) {
+ return ""
+ }
+ for j in 0.. Bool {
+ if let flag = visited[char] {
+ return flag
+ }
+ visited[char] = true
+ for neigh in adj[char]! {
+ if dfs(neigh) {
+ return true
+ }
+ }
+ visited[char] = false
+ res.append(char)
+ return false
+ }
+
+ for char in adj.keys {
+ if dfs(char) {
+ return ""
+ }
+ }
+
+ res.reverse()
+ return String(res)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -823,6 +882,69 @@ class Solution {
}
```
+```swift
+class Solution {
+ func foreignDictionary(_ words: [String]) -> String {
+ var adj = [Character: Set]()
+ for word in words {
+ for char in word {
+ adj[char] = Set()
+ }
+ }
+
+ var indegree = [Character: Int]()
+ for key in adj.keys {
+ indegree[key] = 0
+ }
+
+ for i in 0.. w2.count && String(w1.prefix(minLen)) == String(w2.prefix(minLen)) {
+ return ""
+ }
+ let w1Arr = Array(w1)
+ let w2Arr = Array(w2)
+ for j in 0..()
+ for (c, deg) in indegree {
+ if deg == 0 {
+ q.append(c)
+ }
+ }
+
+ var res = [Character]()
+ while !q.isEmpty {
+ let char = q.removeFirst()
+ res.append(char)
+ for neighbor in adj[char]! {
+ indegree[neighbor]! -= 1
+ if indegree[neighbor]! == 0 {
+ q.append(neighbor)
+ }
+ }
+ }
+
+ if res.count != indegree.count {
+ return ""
+ }
+
+ return String(res)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/gas-station.md b/articles/gas-station.md
index cedbf31c2..9e779b1d8 100644
--- a/articles/gas-station.md
+++ b/articles/gas-station.md
@@ -11,6 +11,7 @@ class Solution:
tank = gas[i] - cost[i]
if tank < 0:
continue
+
j = (i + 1) % n
while j != i:
tank += gas[j]
@@ -19,6 +20,7 @@ class Solution:
break
j += 1
j %= n
+
if j == i:
return i
return -1
@@ -32,12 +34,14 @@ public class Solution {
for (int i = 0; i < n; i++) {
int tank = gas[i] - cost[i];
if (tank < 0) continue;
+
int j = (i + 1) % n;
while (j != i) {
tank += gas[j] - cost[j];
if (tank < 0) break;
j = (j + 1) % n;
}
+
if (j == i) return i;
}
return -1;
@@ -54,12 +58,14 @@ public:
for (int i = 0; i < n; i++) {
int tank = gas[i] - cost[i];
if (tank < 0) continue;
+
int j = (i + 1) % n;
while (j != i) {
tank += gas[j] - cost[j];
if (tank < 0) break;
j = (j + 1) % n;
}
+
if (j == i) return i;
}
return -1;
@@ -80,12 +86,14 @@ class Solution {
for (let i = 0; i < n; i++) {
let tank = gas[i] - cost[i];
if (tank < 0) continue;
+
let j = (i + 1) % n;
while (j !== i) {
tank += gas[j] - cost[j];
if (tank < 0) break;
j = (j + 1) % n;
}
+
if (j === i) return i;
}
return -1;
@@ -101,14 +109,17 @@ public class Solution {
for (int i = 0; i < n; i++) {
int tank = gas[i] - cost[i];
if (tank < 0) continue;
+
int j = (i + 1) % n;
while (j != i) {
tank += gas[j] - cost[j];
if (tank < 0) break;
j = (j + 1) % n;
}
+
if (j == i) return i;
}
+
return -1;
}
}
@@ -117,11 +128,13 @@ public class Solution {
```go
func canCompleteCircuit(gas []int, cost []int) int {
n := len(gas)
+
for i := 0; i < n; i++ {
tank := gas[i] - cost[i]
if tank < 0 {
continue
}
+
j := (i + 1) % n
for j != i {
tank += gas[j]
@@ -131,10 +144,12 @@ func canCompleteCircuit(gas []int, cost []int) int {
}
j = (j + 1) % n
}
+
if j == i {
return i
}
}
+
return -1
}
```
@@ -166,6 +181,38 @@ class Solution {
}
```
+```swift
+class Solution {
+ func canCompleteCircuit(_ gas: [Int], _ cost: [Int]) -> Int {
+ let n = gas.count
+
+ for i in 0.. Int {
+ let n = gas.count
+ var start = n - 1
+ var end = 0
+ var tank = gas[start] - cost[start]
+
+ while start > end {
+ if tank < 0 {
+ start -= 1
+ tank += gas[start] - cost[start]
+ } else {
+ tank += gas[end] - cost[end]
+ end += 1
+ }
+ }
+
+ return tank >= 0 ? start : -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -510,6 +580,29 @@ class Solution {
}
```
+```swift
+class Solution {
+ func canCompleteCircuit(_ gas: [Int], _ cost: [Int]) -> Int {
+ if gas.reduce(0, +) < cost.reduce(0, +) {
+ return -1
+ }
+
+ var total = 0
+ var res = 0
+ for i in 0.. [String] {
+ var res = [String]()
+
+ func isValid(_ s: String) -> Bool {
+ var open = 0
+ for c in s {
+ open += (c == "(") ? 1 : -1
+ if open < 0 {
+ return false
+ }
+ }
+ return open == 0
+ }
+
+ func dfs(_ s: String) {
+ if s.count == n * 2 {
+ if isValid(s) {
+ res.append(s)
+ }
+ return
+ }
+ dfs(s + "(")
+ dfs(s + ")")
+ }
+
+ dfs("")
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -442,6 +475,37 @@ class Solution {
}
```
+```swift
+class Solution {
+ func generateParenthesis(_ n: Int) -> [String] {
+ var stack = [Character]()
+ var res = [String]()
+
+ func backtrack(_ openN: Int, _ closedN: Int) {
+ if openN == n && closedN == n {
+ res.append(String(stack))
+ return
+ }
+
+ if openN < n {
+ stack.append("(")
+ backtrack(openN + 1, closedN)
+ stack.removeLast()
+ }
+
+ if closedN < openN {
+ stack.append(")")
+ backtrack(openN, closedN + 1)
+ stack.removeLast()
+ }
+ }
+
+ backtrack(0, 0)
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -606,6 +670,27 @@ class Solution {
}
```
+```swift
+class Solution {
+ func generateParenthesis(_ n: Int) -> [String] {
+ var res = [[String]](repeating: [], count: n + 1)
+ res[0] = [""]
+
+ for k in 0...n {
+ for i in 0.. count = new HashMap<>();
for (int num : hand) {
count.put(num, count.getOrDefault(num, 0) + 1);
}
+
Arrays.sort(hand);
for (int num : hand) {
if (count.get(num) > 0) {
@@ -45,8 +48,10 @@ class Solution {
public:
bool isNStraightHand(vector& hand, int groupSize) {
if (hand.size() % groupSize != 0) return false;
+
unordered_map count;
for (int num : hand) count[num]++;
+
sort(hand.begin(), hand.end());
for (int num : hand) {
if (count[num] > 0) {
@@ -72,10 +77,12 @@ class Solution {
if (hand.length % groupSize !== 0) {
return false;
}
+
const count = {};
for (const num of hand) {
count[num] = (count[num] || 0) + 1;
}
+
hand.sort((a, b) => a - b);
for (const num of hand) {
if (count[num] > 0) {
@@ -94,10 +101,12 @@ class Solution {
public class Solution {
public bool IsNStraightHand(int[] hand, int groupSize) {
if (hand.Length % groupSize != 0) return false;
+
var count = new Dictionary();
foreach (var num in hand) {
count[num] = count.GetValueOrDefault(num, 0) + 1;
}
+
Array.Sort(hand);
foreach (var num in hand) {
if (count[num] > 0) {
@@ -164,6 +173,36 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isNStraightHand(_ hand: [Int], _ groupSize: Int) -> Bool {
+ if hand.count % groupSize != 0 {
+ return false
+ }
+
+ var count = [Int: Int]()
+ for num in hand {
+ count[num, default: 0] += 1
+ }
+
+ let sortedHand = hand.sorted()
+ for num in sortedHand {
+ if let freq = count[num], freq > 0 {
+ for i in num..<(num + groupSize) {
+ if let f = count[i], f > 0 {
+ count[i] = f - 1
+ } else {
+ return false
+ }
+ }
+ }
+ }
+
+ return true
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -410,6 +449,40 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isNStraightHand(_ hand: [Int], _ groupSize: Int) -> Bool {
+ if hand.count % groupSize != 0 {
+ return false
+ }
+
+ var count = [Int: Int]()
+ for n in hand {
+ count[n, default: 0] += 1
+ }
+
+ var minH = Heap(Array(count.keys))
+
+ while !minH.isEmpty {
+ guard let first = minH.min else { return false }
+
+ for i in first..<(first + groupSize) {
+ guard let freq = count[i] else { return false }
+ count[i] = freq - 1
+ if count[i] == 0 {
+ if i != minH.min {
+ return false
+ }
+ minH.removeMin()
+ }
+ }
+ }
+
+ return true
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -655,6 +728,40 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isNStraightHand(_ hand: [Int], _ groupSize: Int) -> Bool {
+ if hand.count % groupSize != 0 {
+ return false
+ }
+
+ var count = [Int: Int]()
+ for num in hand {
+ count[num, default: 0] += 1
+ }
+
+ var queue = Deque()
+ var lastNum = -1
+ var openGroups = 0
+
+ for (num, numCount) in count.sorted(by: { $0.key < $1.key }) {
+ if (openGroups > 0 && num > lastNum + 1) || openGroups > numCount {
+ return false
+ }
+
+ queue.append(numCount - openGroups)
+ lastNum = num
+ openGroups = numCount
+
+ if queue.count == groupSize {
+ openGroups -= queue.removeFirst()
+ }
+ }
+ return openGroups == 0
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -673,6 +780,7 @@ class Solution:
def isNStraightHand(self, hand: List[int], groupSize: int) -> bool:
if len(hand) % groupSize != 0:
return False
+
count = Counter(hand)
for num in hand:
start = num
@@ -692,6 +800,7 @@ class Solution:
public class Solution {
public boolean isNStraightHand(int[] hand, int groupSize) {
if (hand.length % groupSize != 0) return false;
+
Map count = new HashMap<>();
for (int num : hand) {
count.put(num, count.getOrDefault(num, 0) + 1);
@@ -720,6 +829,7 @@ class Solution {
public:
bool isNStraightHand(vector& hand, int groupSize) {
if (hand.size() % groupSize != 0) return false;
+
unordered_map count;
for (int num : hand) count[num]++;
@@ -750,6 +860,7 @@ class Solution {
*/
isNStraightHand(hand, groupSize) {
if (hand.length % groupSize !== 0) return false;
+
const count = new Map();
hand.forEach(num => count.set(num, (count.get(num) || 0) + 1));
@@ -775,6 +886,7 @@ class Solution {
public class Solution {
public bool IsNStraightHand(int[] hand, int groupSize) {
if (hand.Length % groupSize != 0) return false;
+
Dictionary count = new Dictionary();
foreach (int num in hand) {
if (!count.ContainsKey(num)) count[num] = 0;
@@ -867,6 +979,41 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isNStraightHand(_ hand: [Int], _ groupSize: Int) -> Bool {
+ if hand.count % groupSize != 0 {
+ return false
+ }
+
+ var count = [Int: Int]()
+ for num in hand {
+ count[num, default: 0] += 1
+ }
+
+ for num in hand {
+ var start = num
+ while (count[start - 1] ?? 0) > 0 {
+ start -= 1
+ }
+ while start <= num {
+ while (count[start] ?? 0) > 0 {
+ for i in start..<(start + groupSize) {
+ if (count[i] ?? 0) == 0 {
+ return false
+ }
+ count[i]! -= 1
+ }
+ }
+ start += 1
+ }
+ }
+
+ return true
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/house-robber-ii.md b/articles/house-robber-ii.md
index 9157646c6..0469d73df 100644
--- a/articles/house-robber-ii.md
+++ b/articles/house-robber-ii.md
@@ -131,6 +131,25 @@ class Solution {
}
```
+```swift
+class Solution {
+ func rob(_ nums: [Int]) -> Int {
+ if nums.count == 1 {
+ return nums[0]
+ }
+
+ func dfs(_ i: Int, _ flag: Bool) -> Int {
+ if i >= nums.count || (flag && i == nums.count - 1) {
+ return 0
+ }
+ return max(dfs(i + 1, flag), nums[i] + dfs(i + 2, flag || i == 0))
+ }
+
+ return max(dfs(0, true), dfs(1, false))
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -336,6 +355,35 @@ class Solution {
}
```
+```swift
+class Solution {
+ func rob(_ nums: [Int]) -> Int {
+ if nums.count == 1 {
+ return nums[0]
+ }
+
+ var memo = Array(repeating: Array(repeating: -1, count: 2), count: nums.count)
+
+ func dfs(_ i: Int, _ flag: Bool) -> Int {
+ if i >= nums.count || (flag && i == nums.count - 1) {
+ return 0
+ }
+ if memo[i][flag ? 1 : 0] != -1 {
+ return memo[i][flag ? 1 : 0]
+ }
+
+ memo[i][flag ? 1 : 0] = max(
+ dfs(i + 1, flag), nums[i] + dfs(i + 2, flag || i == 0)
+ )
+
+ return memo[i][flag ? 1 : 0]
+ }
+
+ return max(dfs(0, true), dfs(1, false))
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -553,6 +601,36 @@ class Solution {
}
```
+```swift
+class Solution {
+ func rob(_ nums: [Int]) -> Int {
+ if nums.count == 1 {
+ return nums[0]
+ }
+ return max(helper(Array(nums[1...])), helper(Array(nums[..<(nums.count - 1)])))
+ }
+
+ func helper(_ nums: [Int]) -> Int {
+ if nums.isEmpty {
+ return 0
+ }
+ if nums.count == 1 {
+ return nums[0]
+ }
+
+ var dp = [Int](repeating: 0, count: nums.count)
+ dp[0] = nums[0]
+ dp[1] = max(nums[0], nums[1])
+
+ for i in 2.. Int {
+ if nums.isEmpty {
+ return 0
+ }
+ if nums.count == 1 {
+ return nums[0]
+ }
+
+ let candidate1 = nums[0]
+ let candidate2 = helper(Array(nums[1.. Int {
+ var rob1 = 0
+ var rob2 = 0
+
+ for num in nums {
+ let newRob = max(rob1 + num, rob2)
+ rob1 = rob2
+ rob2 = newRob
+ }
+
+ return rob2
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/house-robber.md b/articles/house-robber.md
index 6122135cb..22be9ba02 100644
--- a/articles/house-robber.md
+++ b/articles/house-robber.md
@@ -118,6 +118,21 @@ class Solution {
}
```
+```swift
+class Solution {
+ func rob(_ nums: [Int]) -> Int {
+ func dfs(_ i: Int) -> Int {
+ if i >= nums.count {
+ return 0
+ }
+ return max(dfs(i + 1), nums[i] + dfs(i + 2))
+ }
+
+ return dfs(0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -291,6 +306,27 @@ class Solution {
}
```
+```swift
+class Solution {
+ func rob(_ nums: [Int]) -> Int {
+ var memo = Array(repeating: -1, count: nums.count)
+
+ func dfs(_ i: Int) -> Int {
+ if i >= nums.count {
+ return 0
+ }
+ if memo[i] != -1 {
+ return memo[i]
+ }
+ memo[i] = max(dfs(i + 1), nums[i] + dfs(i + 2))
+ return memo[i]
+ }
+
+ return dfs(0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -455,6 +491,29 @@ class Solution {
}
```
+```swift
+class Solution {
+ func rob(_ nums: [Int]) -> Int {
+ if nums.isEmpty {
+ return 0
+ }
+ if nums.count == 1 {
+ return nums[0]
+ }
+
+ var dp = Array(repeating: 0, count: nums.count)
+ dp[0] = nums[0]
+ dp[1] = max(nums[0], nums[1])
+
+ for i in 2.. Int {
+ var rob1 = 0, rob2 = 0
+
+ for num in nums {
+ let temp = max(num + rob1, rob2)
+ rob1 = rob2
+ rob2 = temp
+ }
+
+ return rob2
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/implement-prefix-tree.md b/articles/implement-prefix-tree.md
index 493258c7b..3e4a303f2 100644
--- a/articles/implement-prefix-tree.md
+++ b/articles/implement-prefix-tree.md
@@ -363,6 +363,62 @@ class PrefixTree {
}
```
+```swift
+class TrieNode {
+ var children: [TrieNode?]
+ var endOfWord: Bool
+
+ init() {
+ self.children = Array(repeating: nil, count: 26)
+ self.endOfWord = false
+ }
+}
+
+class PrefixTree {
+ private let root: TrieNode
+
+ init() {
+ self.root = TrieNode()
+ }
+
+ func insert(_ word: String) {
+ var cur = root
+ for c in word {
+ let i = Int(c.asciiValue! - Character("a").asciiValue!)
+ if cur.children[i] == nil {
+ cur.children[i] = TrieNode()
+ }
+ cur = cur.children[i]!
+ }
+ cur.endOfWord = true
+ }
+
+ func search(_ word: String) -> Bool {
+ var cur = root
+ for c in word {
+ let i = Int(c.asciiValue! - Character("a").asciiValue!)
+ if cur.children[i] == nil {
+ return false
+ }
+ cur = cur.children[i]!
+ }
+ return cur.endOfWord
+ }
+
+ func startsWith(_ prefix: String) -> Bool {
+ var cur = root
+ for c in prefix {
+ let i = Int(c.asciiValue! - Character("a").asciiValue!)
+ if cur.children[i] == nil {
+ return false
+ }
+ cur = cur.children[i]!
+ }
+ return true
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -708,6 +764,59 @@ class PrefixTree {
}
```
+```swift
+class TrieNode {
+ var children: [Character: TrieNode]
+ var endOfWord: Bool
+
+ init() {
+ self.children = [:]
+ self.endOfWord = false
+ }
+}
+
+class PrefixTree {
+ private let root: TrieNode
+
+ init() {
+ self.root = TrieNode()
+ }
+
+ func insert(_ word: String) {
+ var cur = root
+ for c in word {
+ if cur.children[c] == nil {
+ cur.children[c] = TrieNode()
+ }
+ cur = cur.children[c]!
+ }
+ cur.endOfWord = true
+ }
+
+ func search(_ word: String) -> Bool {
+ var cur = root
+ for c in word {
+ if cur.children[c] == nil {
+ return false
+ }
+ cur = cur.children[c]!
+ }
+ return cur.endOfWord
+ }
+
+ func startsWith(_ prefix: String) -> Bool {
+ var cur = root
+ for c in prefix {
+ if cur.children[c] == nil {
+ return false
+ }
+ cur = cur.children[c]!
+ }
+ return true
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/insert-new-interval.md b/articles/insert-new-interval.md
index 367a09391..13f29a037 100644
--- a/articles/insert-new-interval.md
+++ b/articles/insert-new-interval.md
@@ -216,6 +216,37 @@ class Solution {
}
```
+```swift
+class Solution {
+ func insert(_ intervals: [[Int]], _ newInterval: [Int]) -> [[Int]] {
+ var intervals = intervals
+ var newInterval = newInterval
+ var res: [[Int]] = []
+ var i = 0
+ let n = intervals.count
+
+ while i < n && intervals[i][1] < newInterval[0] {
+ res.append(intervals[i])
+ i += 1
+ }
+
+ while i < n && newInterval[1] >= intervals[i][0] {
+ newInterval[0] = min(newInterval[0], intervals[i][0])
+ newInterval[1] = max(newInterval[1], intervals[i][1])
+ i += 1
+ }
+ res.append(newInterval)
+
+ while i < n {
+ res.append(intervals[i])
+ i += 1
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -512,6 +543,41 @@ class Solution {
}
```
+```swift
+class Solution {
+ func insert(_ intervals: [[Int]], _ newInterval: [Int]) -> [[Int]] {
+ if intervals.isEmpty {
+ return [newInterval]
+ }
+
+ var intervals = intervals
+ let target = newInterval[0]
+ var left = 0, right = intervals.count - 1
+
+ while left <= right {
+ let mid = (left + right) / 2
+ if intervals[mid][0] < target {
+ left = mid + 1
+ } else {
+ right = mid - 1
+ }
+ }
+
+ intervals.insert(newInterval, at: left)
+
+ var res: [[Int]] = []
+ for interval in intervals {
+ if res.isEmpty || res.last![1] < interval[0] {
+ res.append(interval)
+ } else {
+ res[res.count - 1][1] = max(res.last![1], interval[1])
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -707,6 +773,31 @@ class Solution {
}
```
+```swift
+class Solution {
+ func insert(_ intervals: [[Int]], _ newInterval: [Int]) -> [[Int]] {
+ var res = [[Int]]()
+ var newInterval = newInterval
+
+ for i in 0.. intervals[i][1] {
+ res.append(intervals[i])
+ } else {
+ newInterval[0] = min(newInterval[0], intervals[i][0])
+ newInterval[1] = max(newInterval[1], intervals[i][1])
+ }
+ }
+
+ res.append(newInterval)
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/interleaving-string.md b/articles/interleaving-string.md
index c5e0566de..3d124cd01 100644
--- a/articles/interleaving-string.md
+++ b/articles/interleaving-string.md
@@ -199,6 +199,39 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isInterleave(_ s1: String, _ s2: String, _ s3: String) -> Bool {
+ let n1 = s1.count, n2 = s2.count, n3 = s3.count
+ if n1 + n2 != n3 { return false }
+
+ let s1 = Array(s1), s2 = Array(s2), s3 = Array(s3)
+
+ func dfs(_ i: Int, _ j: Int, _ k: Int) -> Bool {
+ if k == n3 {
+ return i == n1 && j == n2
+ }
+
+ if i < n1 && s1[i] == s3[k] {
+ if dfs(i + 1, j, k + 1) {
+ return true
+ }
+ }
+
+ if j < n2 && s2[j] == s3[k] {
+ if dfs(i, j + 1, k + 1) {
+ return true
+ }
+ }
+
+ return false
+ }
+
+ return dfs(0, 0, 0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -462,6 +495,40 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isInterleave(_ s1: String, _ s2: String, _ s3: String) -> Bool {
+ let m = s1.count, n = s2.count, l = s3.count
+ if m + n != l { return false }
+
+ let s1 = Array(s1), s2 = Array(s2), s3 = Array(s3)
+ var dp = Array(repeating: Array(repeating: nil as Bool?, count: n + 1), count: m + 1)
+
+ func dfs(_ i: Int, _ j: Int, _ k: Int) -> Bool {
+ if k == l {
+ return i == m && j == n
+ }
+ if let cached = dp[i][j] {
+ return cached
+ }
+
+ var res = false
+ if i < m && s1[i] == s3[k] {
+ res = dfs(i + 1, j, k + 1)
+ }
+ if !res && j < n && s2[j] == s3[k] {
+ res = dfs(i, j + 1, k + 1)
+ }
+
+ dp[i][j] = res
+ return res
+ }
+
+ return dfs(0, 0, 0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -660,6 +727,31 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isInterleave(_ s1: String, _ s2: String, _ s3: String) -> Bool {
+ let m = s1.count, n = s2.count, l = s3.count
+ if m + n != l { return false }
+
+ let s1 = Array(s1), s2 = Array(s2), s3 = Array(s3)
+ var dp = Array(repeating: Array(repeating: false, count: n + 1), count: m + 1)
+ dp[m][n] = true
+
+ for i in stride(from: m, through: 0, by: -1) {
+ for j in stride(from: n, through: 0, by: -1) {
+ if i < m && s1[i] == s3[i + j] && dp[i + 1][j] {
+ dp[i][j] = true
+ }
+ if j < n && s2[j] == s3[i + j] && dp[i][j + 1] {
+ dp[i][j] = true
+ }
+ }
+ }
+ return dp[0][0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -904,6 +996,38 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isInterleave(_ s1: String, _ s2: String, _ s3: String) -> Bool {
+ var s1 = Array(s1), s2 = Array(s2), s3 = Array(s3)
+ var m = s1.count, n = s2.count
+ if m + n != s3.count { return false }
+ if n < m {
+ swap(&s1, &s2)
+ swap(&m, &n)
+ }
+
+ var dp = Array(repeating: false, count: n + 1)
+ dp[n] = true
+
+ for i in stride(from: m, through: 0, by: -1) {
+ var nextDp = Array(repeating: false, count: n + 1)
+ nextDp[n] = true
+ for j in stride(from: n, through: 0, by: -1) {
+ if i < m && s1[i] == s3[i + j] && dp[j] {
+ nextDp[j] = true
+ }
+ if j < n && s2[j] == s3[i + j] && nextDp[j + 1] {
+ nextDp[j] = true
+ }
+ }
+ dp = nextDp
+ }
+ return dp[0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1155,6 +1279,39 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isInterleave(_ s1: String, _ s2: String, _ s3: String) -> Bool {
+ var s1 = Array(s1), s2 = Array(s2), s3 = Array(s3)
+ var m = s1.count, n = s2.count
+ if m + n != s3.count { return false }
+ if n < m {
+ swap(&s1, &s2)
+ swap(&m, &n)
+ }
+
+ var dp = Array(repeating: false, count: n + 1)
+ dp[n] = true
+
+ for i in stride(from: m, through: 0, by: -1) {
+ var nextDp = true
+ for j in stride(from: n - 1, through: 0, by: -1) {
+ var res = false
+ if i < m && s1[i] == s3[i + j] && dp[j] {
+ res = true
+ }
+ if j < n && s2[j] == s3[i + j] && nextDp {
+ res = true
+ }
+ dp[j] = res
+ nextDp = dp[j]
+ }
+ }
+ return dp[0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/invert-a-binary-tree.md b/articles/invert-a-binary-tree.md
index 2c7622067..33ee15f84 100644
--- a/articles/invert-a-binary-tree.md
+++ b/articles/invert-a-binary-tree.md
@@ -227,6 +227,44 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func invertTree(_ root: TreeNode?) -> TreeNode? {
+ guard let root = root else { return nil }
+ var queue = Deque()
+ queue.append(root)
+
+ while !queue.isEmpty {
+ let node = queue.removeFirst()
+ (node.left, node.right) = (node.right, node.left)
+
+ if let left = node.left {
+ queue.append(left)
+ }
+ if let right = node.right {
+ queue.append(right)
+ }
+ }
+ return root
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -253,10 +291,10 @@ class Solution:
if not root: return None
root.left, root.right = root.right, root.left
-
+
self.invertTree(root.left)
self.invertTree(root.right)
-
+
return root
```
@@ -277,16 +315,18 @@ class Solution:
* }
*/
-class Solution {
+public class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
-
- TreeNode node = new TreeNode(root.val);
- node.right = invertTree(root.left);
- node.left = invertTree(root.right);
-
- return node;
+ TreeNode temp = root.left;
+ root.left = root.right;
+ root.right = temp;
+
+ invertTree(root.left);
+ invertTree(root.right);
+
+ return root;
}
}
```
@@ -307,14 +347,13 @@ class Solution {
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
- if (root == nullptr) return nullptr;
+ if (!root) return nullptr;
- TreeNode* node = new TreeNode(root->val);
-
- node->right = invertTree(root->left);
- node->left = invertTree(root->right);
+ swap(root->left, root->right);
+ invertTree(root->left);
+ invertTree(root->right);
- return node;
+ return root;
}
};
```
@@ -337,14 +376,13 @@ class Solution {
* @return {TreeNode}
*/
invertTree(root) {
- if (root === null) return null;
-
- const node = new TreeNode(root.val);
+ if (!root) return null;
- node.right = this.invertTree(root.left);
- node.left = this.invertTree(root.right);
+ [root.left, root.right] = [root.right, root.left];
+ this.invertTree(root.left);
+ this.invertTree(root.right);
- return node;
+ return root;
}
}
```
@@ -368,12 +406,95 @@ public class Solution {
public TreeNode InvertTree(TreeNode root) {
if (root == null) return null;
- TreeNode node = new TreeNode(root.val);
-
- node.right = InvertTree(root.left);
- node.left = InvertTree(root.right);
+ TreeNode temp = root.left;
+ root.left = root.right;
+ root.right = temp;
+
+ InvertTree(root.left);
+ InvertTree(root.right);
- return node;
+ return root;
+ }
+}
+```
+
+```go
+/**
+ * Definition for a binary tree node.
+ * type TreeNode struct {
+ * Val int
+ * Left *TreeNode
+ * Right *TreeNode
+ * }
+ */
+
+func invertTree(root *TreeNode) *TreeNode {
+ if root == nil {
+ return nil
+ }
+
+ root.Left, root.Right = root.Right, root.Left
+ invertTree(root.Left)
+ invertTree(root.Right)
+
+ return root
+}
+```
+
+```kotlin
+/**
+ * Example:
+ * var ti = TreeNode(5)
+ * var v = ti.`val`
+ * Definition for a binary tree node.
+ * class TreeNode(var `val`: Int) {
+ * var left: TreeNode? = null
+ * var right: TreeNode? = null
+ * }
+ */
+
+class Solution {
+ fun invertTree(root: TreeNode?): TreeNode? {
+ if (root == null) return null
+
+ val temp = root.left
+ root.left = root.right
+ root.right = temp
+
+ invertTree(root.left)
+ invertTree(root.right)
+
+ return root
+ }
+}
+```
+
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func invertTree(_ root: TreeNode?) -> TreeNode? {
+ guard let root = root else { return nil }
+
+ (root.left, root.right) = (root.right, root.left)
+
+ invertTree(root.left)
+ invertTree(root.right)
+
+ return root
}
}
```
@@ -383,7 +504,7 @@ public class Solution {
### Time & Space Complexity
* Time complexity: $O(n)$
-* Space complexity: $O(n)$
+* Space complexity: $O(n)$ for recursion stack.
---
@@ -592,6 +713,43 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func invertTree(_ root: TreeNode?) -> TreeNode? {
+ guard let root = root else { return nil }
+ var stack: [TreeNode] = [root]
+
+ while !stack.isEmpty {
+ let node = stack.removeLast()
+ (node.left, node.right) = (node.right, node.left)
+
+ if let left = node.left {
+ stack.append(left)
+ }
+ if let right = node.right {
+ stack.append(right)
+ }
+ }
+ return root
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/is-anagram.md b/articles/is-anagram.md
index ae3a44534..eb996634a 100644
--- a/articles/is-anagram.md
+++ b/articles/is-anagram.md
@@ -112,6 +112,14 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isAnagram(_ s: String, _ t: String) -> Bool {
+ return s.count == t.count && s.sorted() == t.sorted()
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -123,7 +131,7 @@ class Solution {
---
-## 2. Hash Table
+## 2. Hash Map
::tabs-start
@@ -266,6 +274,29 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isAnagram(_ s: String, _ t: String) -> Bool {
+ if s.count != t.count {
+ return false
+ }
+
+ var countS = [Character: Int]()
+ var countT = [Character: Int]()
+
+ let sArray = Array(s)
+ let tArray = Array(t)
+
+ for i in 0.. Bool {
+ if s.count != t.count {
+ return false
+ }
+
+ var count = [Int](repeating: 0, count: 26)
+ let sArray = Array(s)
+ let tArray = Array(t)
+
+ for i in 0.. Where $n$ is the length of string $s$ and $m$ is the length of string $t$.
+> Where $n$ is the length of string $s$ and $m$ is the length of string $t$.
\ No newline at end of file
diff --git a/articles/is-palindrome.md b/articles/is-palindrome.md
index e7675ceb9..9aea0c833 100644
--- a/articles/is-palindrome.md
+++ b/articles/is-palindrome.md
@@ -123,6 +123,22 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isPalindrome(_ s: String) -> Bool {
+ var newStr = ""
+
+ for c in s {
+ if c.isLetter || c.isNumber {
+ newStr.append(c.lowercased())
+ }
+ }
+
+ return newStr == String(newStr.reversed())
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -327,6 +343,34 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isPalindrome(_ s: String) -> Bool {
+ let chars = Array(s)
+ var l = 0, r = chars.count - 1
+
+ while l < r {
+ while l < r && !isAlphaNum(chars[l]) {
+ l += 1
+ }
+ while r > l && !isAlphaNum(chars[r]) {
+ r -= 1
+ }
+ if chars[l].lowercased() != chars[r].lowercased() {
+ return false
+ }
+ l += 1
+ r -= 1
+ }
+ return true
+ }
+
+ private func isAlphaNum(_ c: Character) -> Bool {
+ return c.isLetter || c.isNumber
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/islands-and-treasure.md b/articles/islands-and-treasure.md
index ff99ef107..86e92192f 100644
--- a/articles/islands-and-treasure.md
+++ b/articles/islands-and-treasure.md
@@ -302,6 +302,43 @@ class Solution {
}
```
+```swift
+class Solution {
+ func islandsAndTreasure(_ grid: inout [[Int]]) {
+ let ROWS = grid.count
+ let COLS = grid[0].count
+ let INF = 2147483647
+ let directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
+ var visit = Array(repeating: Array(repeating: false, count: COLS), count: ROWS)
+
+ func dfs(_ r: Int, _ c: Int) -> Int {
+ if r < 0 || c < 0 || r >= ROWS || c >= COLS || grid[r][c] == -1 || visit[r][c] {
+ return INF
+ }
+ if grid[r][c] == 0 {
+ return 0
+ }
+
+ visit[r][c] = true
+ var res = INF
+ for (dx, dy) in directions {
+ res = min(res, 1 + dfs(r + dx, c + dy))
+ }
+ visit[r][c] = false
+ return res
+ }
+
+ for r in 0.. Int {
+ var q = Deque<(Int, Int)>()
+ q.append((r, c))
+ var visit = Array(repeating: Array(repeating: false, count: COLS), count: ROWS)
+ visit[r][c] = true
+ var steps = 0
+ while !q.isEmpty {
+ let levelCount = q.count
+ for _ in 0..= 0 && nr < ROWS && nc >= 0 && nc < COLS &&
+ !visit[nr][nc] && grid[nr][nc] != -1) {
+ visit[nr][nc] = true
+ q.append((nr, nc))
+ }
+ }
+ }
+ steps += 1
+ }
+ return INF
+ }
+
+ for r in 0..()
+ var q = Deque
- ()
+
+ func addCell(_ r: Int, _ c: Int) {
+ if r < 0 || c < 0 || r >= ROWS || c >= COLS { return }
+ let item = Item(r: r, c: c)
+ if visit.contains(item) || grid[r][c] == -1 { return }
+ visit.insert(item)
+ q.append(item)
+ }
+
+ for r in 0.. Int {
+ func dfs(_ i: Int) -> Int {
+ if i == nums.count - 1 {
+ return 0
+ }
+ if nums[i] == 0 {
+ return 1000000
+ }
+
+ let end = min(nums.count - 1, i + nums[i])
+ var res = 1000000
+ for j in i + 1..<(end + 1) {
+ res = min(res, 1 + dfs(j))
+ }
+
+ return res
+ }
+
+ return dfs(0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -382,6 +411,37 @@ class Solution {
}
```
+```swift
+class Solution {
+ var memo: [Int: Int] = [:]
+
+ func jump(_ nums: [Int]) -> Int {
+ return dfs(nums, 0)
+ }
+
+ private func dfs(_ nums: [Int], _ i: Int) -> Int {
+ if let cachedResult = memo[i] {
+ return cachedResult
+ }
+ if i == nums.count - 1 {
+ return 0
+ }
+ if nums[i] == 0 {
+ return 1000000
+ }
+
+ var res = 1000000
+ let end = min(nums.count, i + nums[i] + 1)
+ for j in i + 1.. Int {
+ let n = nums.count
+ var dp = Array(repeating: 1000000, count: n)
+ dp[n - 1] = 0
+
+ for i in stride(from: n - 2, through: 0, by: -1) {
+ let end = min(n, i + nums[i] + 1)
+ for j in i + 1.. Int {
+ var res = 0
+ var l = 0
+ var r = 0
+
+ while r < nums.count - 1 {
+ var farthest = 0
+ for i in l...r {
+ farthest = max(farthest, i + nums[i])
+ }
+ l = r + 1
+ r = farthest
+ res += 1
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/jump-game.md b/articles/jump-game.md
index 850539bca..c5048055e 100644
--- a/articles/jump-game.md
+++ b/articles/jump-game.md
@@ -157,6 +157,29 @@ class Solution {
}
```
+```swift
+class Solution {
+ func canJump(_ nums: [Int]) -> Bool {
+
+ func dfs(_ i: Int) -> Bool {
+ if i == nums.count - 1 {
+ return true
+ }
+
+ let end = min(nums.count - 1, i + nums[i])
+ for j in i + 1..<(end + 1) {
+ if dfs(j) {
+ return true
+ }
+ }
+ return false
+ }
+
+ return dfs(0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -397,6 +420,39 @@ class Solution {
}
```
+```swift
+class Solution {
+ func canJump(_ nums: [Int]) -> Bool {
+ var memo: [Int: Bool] = [:]
+
+ func dfs(_ i: Int) -> Bool {
+ if let cachedResult = memo[i] {
+ return cachedResult
+ }
+ if i == nums.count - 1 {
+ return true
+ }
+ if nums[i] == 0 {
+ return false
+ }
+
+ let end = min(nums.count, i + nums[i] + 1)
+ for j in i + 1.. Bool {
+ let n = nums.count
+ var dp = [Bool](repeating: false, count: n)
+ dp[n - 1] = true
+
+ for i in (0.. Bool {
+ var goal = nums.count - 1
+
+ for i in stride(from: nums.count - 2, through: 0, by: -1) {
+ if i + nums[i] >= goal {
+ goal = i
+ }
+ }
+
+ return goal == 0
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/k-closest-points-to-origin.md b/articles/k-closest-points-to-origin.md
index 823a5a33f..7882e7c18 100644
--- a/articles/k-closest-points-to-origin.md
+++ b/articles/k-closest-points-to-origin.md
@@ -75,6 +75,16 @@ class Solution {
}
```
+```swift
+class Solution {
+ func kClosest(_ points: [[Int]], _ k: Int) -> [[Int]] {
+ return points.sorted { ($0[0] * $0[0] + $0[1] * $0[1]) < ($1[0] * $1[0] + $1[1] * $1[1]) }
+ .prefix(k)
+ .map { $0 }
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -84,7 +94,7 @@ class Solution {
---
-## 2. Min Heap
+## 2. Min-Heap
::tabs-start
@@ -242,6 +252,39 @@ class Solution {
}
```
+```swift
+struct Item: Comparable {
+ let dist: Int
+ let x: Int
+ let y: Int
+
+ static func < (lhs: Item, rhs: Item) -> Bool {
+ return lhs.dist < rhs.dist
+ }
+}
+
+class Solution {
+ func kClosest(_ points: [[Int]], _ k: Int) -> [[Int]] {
+ var minHeap = Heap
- ()
+
+ for point in points {
+ let x = point[0], y = point[1]
+ let dist = x * x + y * y
+ minHeap.insert(Item(dist: dist, x: x, y: y))
+ }
+
+ var res = [[Int]]()
+ for _ in 0.. Bool {
+ return lhs.dist > rhs.dist
+ }
+}
+
+class Solution {
+ func kClosest(_ points: [[Int]], _ k: Int) -> [[Int]] {
+ var maxHeap = Heap
- ()
+
+ for point in points {
+ let x = point[0], y = point[1]
+ let dist = x * x + y * y
+ maxHeap.insert(Item(dist: dist, x: x, y: y))
+ if maxHeap.count > k {
+ _ = maxHeap.popMin()
+ }
+ }
+
+ var res = [[Int]]()
+ while !maxHeap.isEmpty {
+ if let item = maxHeap.popMin() {
+ res.append([item.x, item.y])
+ }
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -721,6 +800,46 @@ class Solution {
}
```
+```swift
+class Solution {
+ func kClosest(_ points: [[Int]], _ k: Int) -> [[Int]] {
+ var points = points
+
+ func euclidean(_ point: [Int]) -> Int {
+ return point[0] * point[0] + point[1] * point[1]
+ }
+
+ func partition(_ l: Int, _ r: Int) -> Int {
+ let pivotIdx = r
+ let pivotDist = euclidean(points[pivotIdx])
+ var i = l
+ for j in l.. Int {
+ let sortedNums = nums.sorted()
+ return sortedNums[sortedNums.count - k]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -184,6 +193,23 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findKthLargest(_ nums: [Int], _ k: Int) -> Int {
+ var minHeap = Heap()
+
+ for num in nums {
+ minHeap.insert(num)
+ if minHeap.count > k {
+ _ = minHeap.removeMin()
+ }
+ }
+
+ return minHeap.popMin()!
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -417,6 +443,38 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findKthLargest(_ nums: [Int], _ k: Int) -> Int {
+ var nums = nums
+ let k = nums.count - k
+
+ func quickSelect(_ l: Int, _ r: Int) -> Int {
+ let pivot = nums[r]
+ var p = l
+
+ for i in l.. k {
+ return quickSelect(l, p - 1)
+ } else if p < k {
+ return quickSelect(p + 1, r)
+ } else {
+ return nums[p]
+ }
+ }
+
+ return quickSelect(0, nums.count - 1)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -822,6 +880,70 @@ class Solution {
}
```
+```swift
+class Solution {
+ func partition(_ nums: inout [Int], _ left: Int, _ right: Int) -> Int {
+ let mid = (left + right) >> 1
+ nums.swapAt(mid, left + 1)
+
+ if nums[left] < nums[right] {
+ nums.swapAt(left, right)
+ }
+ if nums[left + 1] < nums[right] {
+ nums.swapAt(left + 1, right)
+ }
+ if nums[left] < nums[left + 1] {
+ nums.swapAt(left, left + 1)
+ }
+
+ let pivot = nums[left + 1]
+ var i = left + 1
+ var j = right
+
+ while true {
+ repeat { i += 1 } while nums[i] > pivot
+ repeat { j -= 1 } while nums[j] < pivot
+
+ if i > j {
+ break
+ }
+ nums.swapAt(i, j)
+ }
+
+ nums.swapAt(left + 1, j)
+ return j
+ }
+
+ func quickSelect(_ nums: inout [Int], _ k: Int) -> Int {
+ var left = 0
+ var right = nums.count - 1
+
+ while true {
+ if right <= left + 1 {
+ if right == left + 1 && nums[right] > nums[left] {
+ nums.swapAt(left, right)
+ }
+ return nums[k]
+ }
+
+ let j = partition(&nums, left, right)
+
+ if j >= k {
+ right = j - 1
+ }
+ if j <= k {
+ left = j + 1
+ }
+ }
+ }
+
+ func findKthLargest(_ nums: [Int], _ k: Int) -> Int {
+ var nums = nums
+ return quickSelect(&nums, k - 1)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/kth-largest-integer-in-a-stream.md b/articles/kth-largest-integer-in-a-stream.md
index 7913b93ca..42a4f617a 100644
--- a/articles/kth-largest-integer-in-a-stream.md
+++ b/articles/kth-largest-integer-in-a-stream.md
@@ -124,12 +124,32 @@ class KthLargest(k: Int, nums: IntArray) {
}
```
+```swift
+class KthLargest {
+ private var k: Int
+ private var arr: [Int]
+
+ init(_ k: Int, _ nums: [Int]) {
+ self.k = k
+ self.arr = nums
+ }
+
+ func add(_ val: Int) -> Int {
+ arr.append(val)
+ arr.sort()
+ return arr[arr.count - k]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(m * n\log n)$
-* Space complexity: $O(1)$ or $O(n)$ depending on the sorting algorithm.
+* Space complexity:
+ * $O(m)$ extra space.
+ * $O(1)$ or $O(n)$ space depending on the sorting algorithm.
> Where $m$ is the number of calls made to $add()$ and $n$ is the current size of the array.
@@ -324,6 +344,32 @@ class KthLargest(k: Int, nums: IntArray) {
}
```
+```swift
+class KthLargest {
+ private var minHeap: Heap
+ private let k: Int
+
+ init(_ k: Int, _ nums: [Int]) {
+ self.k = k
+ self.minHeap = Heap()
+ for num in nums {
+ minHeap.insert(num)
+ if minHeap.count > k {
+ minHeap.popMin()
+ }
+ }
+ }
+
+ func add(_ val: Int) -> Int {
+ minHeap.insert(val)
+ if minHeap.count > k {
+ minHeap.popMin()
+ }
+ return minHeap.min!
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/kth-smallest-integer-in-bst.md b/articles/kth-smallest-integer-in-bst.md
index 1014ba6d4..ec5dfe795 100644
--- a/articles/kth-smallest-integer-in-bst.md
+++ b/articles/kth-smallest-integer-in-bst.md
@@ -225,6 +225,40 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func kthSmallest(_ root: TreeNode?, _ k: Int) -> Int {
+ var arr = [Int]()
+
+ func dfs(_ node: TreeNode?) {
+ guard let node = node else { return }
+ arr.append(node.val)
+ dfs(node.left)
+ dfs(node.right)
+ }
+
+ dfs(root)
+ arr.sort()
+ return arr[k - 1]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -456,6 +490,39 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func kthSmallest(_ root: TreeNode?, _ k: Int) -> Int {
+ var arr = [Int]()
+
+ func dfs(_ node: TreeNode?) {
+ guard let node = node else { return }
+ dfs(node.left)
+ arr.append(node.val)
+ dfs(node.right)
+ }
+
+ dfs(root)
+ return arr[k - 1]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -721,6 +788,45 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func kthSmallest(_ root: TreeNode?, _ k: Int) -> Int {
+ var cnt = k
+ var res = root!.val
+
+ func dfs(_ node: TreeNode?) {
+ guard let node = node else { return }
+
+ dfs(node.left)
+ cnt -= 1
+ if cnt == 0 {
+ res = node.val
+ return
+ }
+ dfs(node.right)
+ }
+
+ dfs(root)
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -983,6 +1089,45 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func kthSmallest(_ root: TreeNode?, _ k: Int) -> Int {
+ var stack = [TreeNode]()
+ var curr = root
+ var k = k
+
+ while !stack.isEmpty || curr != nil {
+ while curr != nil {
+ stack.append(curr!)
+ curr = curr?.left
+ }
+ curr = stack.removeLast()
+ k -= 1
+ if k == 0 {
+ return curr!.val
+ }
+ curr = curr?.right
+ }
+ return -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1298,6 +1443,58 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func kthSmallest(_ root: TreeNode?, _ k: Int) -> Int {
+ var curr = root
+ var k = k
+
+ while curr != nil {
+ if curr?.left == nil {
+ k -= 1
+ if k == 0 {
+ return curr!.val
+ }
+ curr = curr?.right
+ } else {
+ var pred = curr?.left
+ while pred?.right != nil && pred?.right !== curr {
+ pred = pred?.right
+ }
+
+ if pred?.right == nil {
+ pred?.right = curr
+ curr = curr?.left
+ } else {
+ pred?.right = nil
+ k -= 1
+ if k == 0 {
+ return curr!.val
+ }
+ curr = curr?.right
+ }
+ }
+ }
+ return -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/largest-rectangle-in-histogram.md b/articles/largest-rectangle-in-histogram.md
index 54d44de5b..75df88ffe 100644
--- a/articles/largest-rectangle-in-histogram.md
+++ b/articles/largest-rectangle-in-histogram.md
@@ -203,6 +203,35 @@ class Solution {
}
```
+```swift
+class Solution {
+ func largestRectangleArea(_ heights: [Int]) -> Int {
+ let n = heights.count
+ var maxArea = 0
+
+ for i in 0..= height {
+ rightMost += 1
+ }
+
+ var leftMost = i
+ while leftMost >= 0 && heights[leftMost] >= height {
+ leftMost -= 1
+ }
+
+ rightMost -= 1
+ leftMost += 1
+ maxArea = max(maxArea, height * (rightMost - leftMost + 1))
+ }
+
+ return maxArea
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -767,6 +796,86 @@ class Solution {
}
```
+```swift
+class MinIdxSegmentTree {
+ private var n: Int
+ private var INF = Int(1e9)
+ private var A: [Int]
+ private var tree: [Int]
+
+ init(_ N: Int, _ A: [Int]) {
+ self.n = N
+ self.A = A
+ while (self.n & (self.n - 1)) != 0 {
+ self.A.append(self.INF)
+ self.n += 1
+ }
+ self.tree = [Int](repeating: 0, count: 2 * self.n)
+ build()
+ }
+
+ private func build() {
+ for i in 0..> 1
+ while j >= 1 {
+ let a = tree[j << 1]
+ let b = tree[(j << 1) + 1]
+ tree[j] = (A[a] <= A[b]) ? a : b
+ j >>= 1
+ }
+ }
+
+ func query(_ ql: Int, _ qh: Int) -> Int {
+ return _query(1, 0, n - 1, ql, qh)
+ }
+
+ private func _query(_ node: Int, _ l: Int, _ h: Int, _ ql: Int, _ qh: Int) -> Int {
+ if ql > h || qh < l {
+ return INF
+ }
+ if l >= ql && h <= qh {
+ return tree[node]
+ }
+ let a = _query(node << 1, l, (l + h) >> 1, ql, qh)
+ let b = _query((node << 1) + 1, ((l + h) >> 1) + 1, h, ql, qh)
+ if a == INF { return b }
+ if b == INF { return a }
+ return (A[a] <= A[b]) ? a : b
+ }
+}
+
+class Solution {
+ func getMaxArea(_ heights: [Int], _ l: Int, _ r: Int, _ st: MinIdxSegmentTree) -> Int {
+ if l > r { return 0 }
+ if l == r { return heights[l] }
+
+ let minIdx = st.query(l, r)
+ return max(
+ max(getMaxArea(heights, l, minIdx - 1, st),
+ getMaxArea(heights, minIdx + 1, r, st)),
+ (r - l + 1) * heights[minIdx]
+ )
+ }
+
+ func largestRectangleArea(_ heights: [Int]) -> Int {
+ let n = heights.count
+ let st = MinIdxSegmentTree(n, heights)
+ return getMaxArea(heights, 0, n - 1, st)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1075,6 +1184,46 @@ class Solution {
}
```
+```swift
+class Solution {
+ func largestRectangleArea(_ heights: [Int]) -> Int {
+ let n = heights.count
+ var stack = [Int]()
+
+ var leftMost = [Int](repeating: -1, count: n)
+ for i in 0..= heights[i] {
+ stack.removeLast()
+ }
+ if !stack.isEmpty {
+ leftMost[i] = stack.last!
+ }
+ stack.append(i)
+ }
+
+ stack.removeAll()
+ var rightMost = [Int](repeating: n, count: n)
+ for i in stride(from: n - 1, through: 0, by: -1) {
+ while !stack.isEmpty && heights[stack.last!] >= heights[i] {
+ stack.removeLast()
+ }
+ if !stack.isEmpty {
+ rightMost[i] = stack.last!
+ }
+ stack.append(i)
+ }
+
+ var maxArea = 0
+ for i in 0.. Int {
+ var maxArea = 0
+ var stack = [(Int, Int)]() // Pair: (index, height)
+
+ for (i, h) in heights.enumerated() {
+ var start = i
+ while !stack.isEmpty && stack.last!.1 > h {
+ let (index, height) = stack.removeLast()
+ maxArea = max(maxArea, height * (i - index))
+ start = index
+ }
+ stack.append((start, h))
+ }
+
+ for (i, h) in stack {
+ maxArea = max(maxArea, h * (heights.count - i))
+ }
+
+ return maxArea
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1292,7 +1466,7 @@ class Solution {
---
-## 5. Stack (One Pass)
+## 5. Stack (Optimal)
::tabs-start
@@ -1453,6 +1627,26 @@ class Solution {
}
```
+```swift
+class Solution {
+ func largestRectangleArea(_ heights: [Int]) -> Int {
+ let n = heights.count
+ var maxArea = 0
+ var stack = [Int]()
+
+ for i in 0...n {
+ while !stack.isEmpty && (i == n || heights[stack.last!] >= heights[i]) {
+ let height = heights[stack.removeLast()]
+ let width = stack.isEmpty ? i : i - stack.last! - 1
+ maxArea = max(maxArea, height * width)
+ }
+ stack.append(i)
+ }
+ return maxArea
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/last-stone-weight.md b/articles/last-stone-weight.md
index da1ec745e..69ab3403a 100644
--- a/articles/last-stone-weight.md
+++ b/articles/last-stone-weight.md
@@ -127,6 +127,24 @@ class Solution {
}
```
+```swift
+class Solution {
+ func lastStoneWeight(_ stones: [Int]) -> Int {
+ var stones = stones
+
+ while stones.count > 1 {
+ stones.sort()
+ let cur = stones.removeLast() - stones.removeLast()
+ if cur > 0 {
+ stones.append(cur)
+ }
+ }
+
+ return stones.isEmpty ? 0 : stones[0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -368,6 +386,40 @@ class Solution {
}
```
+```swift
+class Solution {
+ func lastStoneWeight(_ stones: [Int]) -> Int {
+ var stones = stones.sorted()
+ var n = stones.count
+
+ while n > 1 {
+ let cur = stones.removeLast() - stones.removeLast()
+ n -= 2
+ if cur > 0 {
+ var l = 0, r = n
+ while l < r {
+ let mid = (l + r) / 2
+ if stones[mid] < cur {
+ l = mid + 1
+ } else {
+ r = mid
+ }
+ }
+ let pos = l
+ stones.append(0)
+ n += 1
+ for i in stride(from: n - 1, to: pos, by: -1) {
+ stones[i] = stones[i - 1]
+ }
+ stones[pos] = cur
+ }
+ }
+
+ return n > 0 ? stones[0] : 0
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -543,6 +595,22 @@ class Solution {
}
```
+```swift
+class Solution {
+ func lastStoneWeight(_ stones: [Int]) -> Int {
+ var heap = Heap(stones)
+ while heap.count > 1 {
+ let first = heap.popMax()!
+ let second = heap.popMax()!
+ if first > second {
+ heap.insert(first - second)
+ }
+ }
+ return heap.isEmpty ? 0 : heap.popMax()!
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -843,6 +911,46 @@ class Solution {
}
```
+```swift
+class Solution {
+ func lastStoneWeight(_ stones: [Int]) -> Int {
+ guard let maxStone = stones.max() else { return 0 }
+
+ var bucket = [Int](repeating: 0, count: maxStone + 1)
+ for stone in stones {
+ bucket[stone] += 1
+ }
+
+ var first = maxStone
+ var second = maxStone
+
+ while first > 0 {
+ if bucket[first] % 2 == 0 {
+ first -= 1
+ continue
+ }
+
+ var j = min(first - 1, second)
+ while j > 0 && bucket[j] == 0 {
+ j -= 1
+ }
+
+ if j == 0 {
+ return first
+ }
+
+ second = j
+ bucket[first] -= 1
+ bucket[second] -= 1
+ bucket[first - second] += 1
+ first = max(first - second, second)
+ }
+
+ return first
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/level-order-traversal-of-binary-tree.md b/articles/level-order-traversal-of-binary-tree.md
index 3bb08fe9a..28df7fc5f 100644
--- a/articles/level-order-traversal-of-binary-tree.md
+++ b/articles/level-order-traversal-of-binary-tree.md
@@ -19,11 +19,11 @@ class Solution:
return None
if len(res) == depth:
res.append([])
-
+
res[depth].append(node.val)
dfs(node.left, depth + 1)
dfs(node.right, depth + 1)
-
+
dfs(root, 0)
return res
```
@@ -251,6 +251,44 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func levelOrder(_ root: TreeNode?) -> [[Int]] {
+ var res = [[Int]]()
+
+ func dfs(_ node: TreeNode?, _ depth: Int) {
+ guard let node = node else { return }
+
+ if res.count == depth {
+ res.append([])
+ }
+
+ res[depth].append(node.val)
+ dfs(node.left, depth + 1)
+ dfs(node.right, depth + 1)
+ }
+
+ dfs(root, 0)
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -549,6 +587,48 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func levelOrder(_ root: TreeNode?) -> [[Int]] {
+ var res = [[Int]]()
+ var q = Deque()
+ q.append(root)
+
+ while !q.isEmpty {
+ let qLen = q.count
+ var level = [Int]()
+
+ for _ in 0.. Bool {
+ var seen = Set()
+ var cur = head
+
+ while cur != nil {
+ let nodeId = ObjectIdentifier(cur!)
+ if seen.contains(nodeId) {
+ return true
+ }
+ seen.insert(nodeId)
+ cur = cur?.next
+ }
+ return false
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -387,6 +418,36 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init(_ val: Int) {
+ * self.val = val
+ * self.next = nil
+ * }
+ * }
+ */
+
+class Solution {
+ func hasCycle(_ head: ListNode?) -> Bool {
+ var slow = head
+ var fast = head
+
+ while fast != nil && fast?.next != nil {
+ slow = slow?.next
+ fast = fast?.next?.next
+ if slow === fast {
+ return true
+ }
+ }
+ return false
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/longest-common-subsequence.md b/articles/longest-common-subsequence.md
index f75a48573..95c23cd86 100644
--- a/articles/longest-common-subsequence.md
+++ b/articles/longest-common-subsequence.md
@@ -136,6 +136,27 @@ class Solution {
}
```
+```swift
+class Solution {
+ func longestCommonSubsequence(_ text1: String, _ text2: String) -> Int {
+ let arr1 = Array(text1)
+ let arr2 = Array(text2)
+
+ func dfs(_ i: Int, _ j: Int) -> Int {
+ if i == arr1.count || j == arr2.count {
+ return 0
+ }
+ if arr1[i] == arr2[j] {
+ return 1 + dfs(i + 1, j + 1)
+ }
+ return max(dfs(i + 1, j), dfs(i, j + 1))
+ }
+
+ return dfs(0, 0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -363,6 +384,35 @@ class Solution {
}
```
+```swift
+class Solution {
+ func longestCommonSubsequence(_ text1: String, _ text2: String) -> Int {
+ let arr1 = Array(text1)
+ let arr2 = Array(text2)
+ var memo = [String: Int]()
+
+ func dfs(_ i: Int, _ j: Int) -> Int {
+ if i == arr1.count || j == arr2.count {
+ return 0
+ }
+ let key = "\(i),\(j)"
+ if let val = memo[key] {
+ return val
+ }
+
+ if arr1[i] == arr2[j] {
+ memo[key] = 1 + dfs(i + 1, j + 1)
+ } else {
+ memo[key] = max(dfs(i + 1, j), dfs(i, j + 1))
+ }
+ return memo[key]!
+ }
+
+ return dfs(0, 0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -534,6 +584,31 @@ class Solution {
}
```
+```swift
+class Solution {
+ func longestCommonSubsequence(_ text1: String, _ text2: String) -> Int {
+ let m = text1.count
+ let n = text2.count
+ let arr1 = Array(text1)
+ let arr2 = Array(text2)
+
+ var dp = Array(repeating: Array(repeating: 0, count: n + 1), count: m + 1)
+
+ for i in stride(from: m - 1, through: 0, by: -1) {
+ for j in stride(from: n - 1, through: 0, by: -1) {
+ if arr1[i] == arr2[j] {
+ dp[i][j] = 1 + dp[i + 1][j + 1]
+ } else {
+ dp[i][j] = max(dp[i][j + 1], dp[i + 1][j])
+ }
+ }
+ }
+
+ return dp[0][0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -749,6 +824,35 @@ class Solution {
}
```
+```swift
+class Solution {
+ func longestCommonSubsequence(_ text1: String, _ text2: String) -> Int {
+ var t1 = Array(text1)
+ var t2 = Array(text2)
+
+ if t1.count < t2.count {
+ swap(&t1, &t2)
+ }
+
+ var prev = Array(repeating: 0, count: t2.count + 1)
+ var curr = Array(repeating: 0, count: t2.count + 1)
+
+ for i in stride(from: t1.count - 1, through: 0, by: -1) {
+ for j in stride(from: t2.count - 1, through: 0, by: -1) {
+ if t1[i] == t2[j] {
+ curr[j] = 1 + prev[j + 1]
+ } else {
+ curr[j] = max(curr[j + 1], prev[j])
+ }
+ }
+ swap(&prev, &curr)
+ }
+
+ return prev[0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -966,6 +1070,36 @@ class Solution {
}
```
+```swift
+class Solution {
+ func longestCommonSubsequence(_ text1: String, _ text2: String) -> Int {
+ var t1 = Array(text1)
+ var t2 = Array(text2)
+
+ if t1.count < t2.count {
+ swap(&t1, &t2)
+ }
+
+ var dp = Array(repeating: 0, count: t2.count + 1)
+
+ for i in stride(from: t1.count - 1, through: 0, by: -1) {
+ var prev = 0
+ for j in stride(from: t2.count - 1, through: 0, by: -1) {
+ let temp = dp[j]
+ if t1[i] == t2[j] {
+ dp[j] = 1 + prev
+ } else {
+ dp[j] = max(dp[j], dp[j + 1])
+ }
+ prev = temp
+ }
+ }
+
+ return dp[0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/longest-consecutive-sequence.md b/articles/longest-consecutive-sequence.md
index 9f7193486..22cd5db3f 100644
--- a/articles/longest-consecutive-sequence.md
+++ b/articles/longest-consecutive-sequence.md
@@ -143,6 +143,29 @@ class Solution {
}
```
+```swift
+class Solution {
+ func longestConsecutive(_ nums: [Int]) -> Int {
+ var res = 0
+ let store = Set(nums)
+
+ for num in nums {
+ var streak = 0
+ var curr = num
+
+ while store.contains(curr) {
+ streak += 1
+ curr += 1
+ }
+
+ res = max(res, streak)
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -343,12 +366,44 @@ class Solution {
}
```
+```swift
+class Solution {
+ func longestConsecutive(_ nums: [Int]) -> Int {
+ if nums.isEmpty {
+ return 0
+ }
+
+ var res = 0
+ var nums = nums.sorted()
+
+ var curr = nums[0]
+ var streak = 0
+ var i = 0
+
+ while i < nums.count {
+ if curr != nums[i] {
+ curr = nums[i]
+ streak = 0
+ }
+ while i < nums.count && nums[i] == curr {
+ i += 1
+ }
+ streak += 1
+ curr += 1
+ res = max(res, streak)
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(n \log n)$
-* Space complexity: $O(1)$
+* Space complexity: $O(1)$ or $O(n)$ depending on the sorting algorithm.
---
@@ -506,6 +561,27 @@ class Solution {
}
```
+```swift
+class Solution {
+ func longestConsecutive(_ nums: [Int]) -> Int {
+ let numSet = Set(nums)
+ var longest = 0
+
+ for num in numSet {
+ if !numSet.contains(num - 1) {
+ var length = 1
+ while numSet.contains(num + length) {
+ length += 1
+ }
+ longest = max(length, longest)
+ }
+ }
+
+ return longest
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -662,6 +738,31 @@ class Solution {
}
```
+```swift
+class Solution {
+ func longestConsecutive(_ nums: [Int]) -> Int {
+ var mp = [Int: Int]()
+ var res = 0
+
+ for num in nums {
+ if mp[num] == nil {
+ let left = mp[num - 1] ?? 0
+ let right = mp[num + 1] ?? 0
+ let length = left + right + 1
+
+ mp[num] = length
+ mp[num - left] = length
+ mp[num + right] = length
+
+ res = max(res, length)
+ }
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/longest-increasing-path-in-matrix.md b/articles/longest-increasing-path-in-matrix.md
index 950ac6e73..e529b1ded 100644
--- a/articles/longest-increasing-path-in-matrix.md
+++ b/articles/longest-increasing-path-in-matrix.md
@@ -230,6 +230,35 @@ class Solution {
}
```
+```swift
+class Solution {
+ func longestIncreasingPath(_ matrix: [[Int]]) -> Int {
+ let rows = matrix.count, cols = matrix[0].count
+ let directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
+
+ func dfs(_ r: Int, _ c: Int, _ prevVal: Int) -> Int {
+ if r < 0 || c < 0 || r >= rows || c >= cols || matrix[r][c] <= prevVal {
+ return 0
+ }
+
+ var res = 1
+ for (dr, dc) in directions {
+ res = max(res, 1 + dfs(r + dr, c + dc, matrix[r][c]))
+ }
+ return res
+ }
+
+ var lip = 0
+ for r in 0.. Int {
+ let rows = matrix.count, cols = matrix[0].count
+ var dp = Array(repeating: Array(repeating: -1, count: cols), count: rows)
+
+ func dfs(_ r: Int, _ c: Int, _ prevVal: Int) -> Int {
+ if r < 0 || r >= rows || c < 0 || c >= cols || matrix[r][c] <= prevVal {
+ return 0
+ }
+ if dp[r][c] != -1 {
+ return dp[r][c]
+ }
+
+ var res = 1
+ res = max(res, 1 + dfs(r + 1, c, matrix[r][c]))
+ res = max(res, 1 + dfs(r - 1, c, matrix[r][c]))
+ res = max(res, 1 + dfs(r, c + 1, matrix[r][c]))
+ res = max(res, 1 + dfs(r, c - 1, matrix[r][c]))
+
+ dp[r][c] = res
+ return res
+ }
+
+ var maxPath = 0
+ for r in 0.. Int {
+ let rows = matrix.count, cols = matrix[0].count
+ let directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
+ var indegree = Array(repeating: Array(repeating: 0, count: cols), count: rows)
+
+ for r in 0..= 0 && nr < rows && nc >= 0 && nc < cols &&
+ matrix[nr][nc] < matrix[r][c]) {
+ indegree[r][c] += 1
+ }
+ }
+ }
+ }
+
+ var q = Deque<(Int, Int)>()
+ for r in 0..= 0 && nr < rows && nc >= 0 && nc < cols &&
+ matrix[nr][nc] > matrix[r][c]) {
+ indegree[nr][nc] -= 1
+ if indegree[nr][nc] == 0 {
+ q.append((nr, nc))
+ }
+ }
+ }
+ }
+ LIS += 1
+ }
+ return LIS
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/longest-increasing-subsequence.md b/articles/longest-increasing-subsequence.md
index 1b24412eb..79391921a 100644
--- a/articles/longest-increasing-subsequence.md
+++ b/articles/longest-increasing-subsequence.md
@@ -170,6 +170,28 @@ class Solution {
}
```
+```swift
+class Solution {
+ func lengthOfLIS(_ nums: [Int]) -> Int {
+ func dfs(_ i: Int, _ j: Int) -> Int {
+ if i == nums.count {
+ return 0
+ }
+
+ var LIS = dfs(i + 1, j) // not include
+
+ if j == -1 || nums[j] < nums[i] {
+ LIS = max(LIS, 1 + dfs(i + 1, i)) // include
+ }
+
+ return LIS
+ }
+
+ return dfs(0, -1)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -179,7 +201,7 @@ class Solution {
---
-## 2. Dynamic Programming (Top-Down)
+## 2. Dynamic Programming (Top-Down) - I
::tabs-start
@@ -410,6 +432,508 @@ class Solution {
}
```
+```swift
+class Solution {
+ func lengthOfLIS(_ nums: [Int]) -> Int {
+ let n = nums.count
+ var memo = Array(repeating: Array(repeating: -1, count: n + 1), count: n)
+
+ func dfs(_ i: Int, _ j: Int) -> Int {
+ if i == n {
+ return 0
+ }
+ if memo[i][j + 1] != -1 {
+ return memo[i][j + 1]
+ }
+
+ var LIS = dfs(i + 1, j) // not include
+
+ if j == -1 || nums[j] < nums[i] {
+ LIS = max(LIS, 1 + dfs(i + 1, i)) // include
+ }
+
+ memo[i][j + 1] = LIS
+ return LIS
+ }
+
+ return dfs(0, -1)
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n ^ 2)$
+* Space complexity: $O(n ^ 2)$
+
+---
+
+## 3. Dynamic Programming (Top-Down) - II
+
+::tabs-start
+
+```python
+class Solution:
+ def lengthOfLIS(self, nums: List[int]) -> int:
+ n = len(nums)
+ memo = [-1] * n
+
+ def dfs(i):
+ if memo[i] != -1:
+ return memo[i]
+
+ LIS = 1
+ for j in range(i + 1, n):
+ if nums[i] < nums[j]:
+ LIS = max(LIS, 1 + dfs(j))
+
+ memo[i] = LIS
+ return LIS
+
+ return max(dfs(i) for i in range(n))
+```
+
+```java
+public class Solution {
+ private int[] memo;
+
+ public int lengthOfLIS(int[] nums) {
+ int n = nums.length;
+ memo = new int[n];
+ Arrays.fill(memo, -1);
+
+ int maxLIS = 1;
+ for (int i = 0; i < n; i++) {
+ maxLIS = Math.max(maxLIS, dfs(nums, i));
+ }
+ return maxLIS;
+ }
+
+ private int dfs(int[] nums, int i) {
+ if (memo[i] != -1) {
+ return memo[i];
+ }
+
+ int LIS = 1;
+ for (int j = i + 1; j < nums.length; j++) {
+ if (nums[i] < nums[j]) {
+ LIS = Math.max(LIS, 1 + dfs(nums, j));
+ }
+ }
+
+ memo[i] = LIS;
+ return LIS;
+ }
+}
+```
+
+```cpp
+class Solution {
+private:
+ vector memo;
+
+ int dfs(vector& nums, int i) {
+ if (memo[i] != -1) {
+ return memo[i];
+ }
+
+ int LIS = 1;
+ for (int j = i + 1; j < nums.size(); j++) {
+ if (nums[i] < nums[j]) {
+ LIS = max(LIS, 1 + dfs(nums, j));
+ }
+ }
+
+ return memo[i] = LIS;
+ }
+
+public:
+ int lengthOfLIS(vector& nums) {
+ int n = nums.size();
+ memo.assign(n, -1);
+
+ int maxLIS = 1;
+ for (int i = 0; i < n; i++) {
+ maxLIS = max(maxLIS, dfs(nums, i));
+ }
+ return maxLIS;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} nums
+ * @return {number}
+ */
+ lengthOfLIS(nums) {
+ const n = nums.length;
+ const memo = new Array(n).fill(-1);
+
+ const dfs = (i) => {
+ if (memo[i] !== -1) {
+ return memo[i];
+ }
+
+ let LIS = 1;
+ for (let j = i + 1; j < n; j++) {
+ if (nums[i] < nums[j]) {
+ LIS = Math.max(LIS, 1 + dfs(j));
+ }
+ }
+
+ memo[i] = LIS;
+ return LIS;
+ };
+
+ return Math.max(...nums.map((_, i) => dfs(i)));
+ }
+}
+```
+
+```csharp
+public class Solution {
+ private int[] memo;
+
+ public int LengthOfLIS(int[] nums) {
+ int n = nums.Length;
+ memo = new int[n];
+ Array.Fill(memo, -1);
+
+ int maxLIS = 1;
+ for (int i = 0; i < n; i++) {
+ maxLIS = Math.Max(maxLIS, Dfs(nums, i));
+ }
+ return maxLIS;
+ }
+
+ private int Dfs(int[] nums, int i) {
+ if (memo[i] != -1) {
+ return memo[i];
+ }
+
+ int LIS = 1;
+ for (int j = i + 1; j < nums.Length; j++) {
+ if (nums[i] < nums[j]) {
+ LIS = Math.Max(LIS, 1 + Dfs(nums, j));
+ }
+ }
+
+ memo[i] = LIS;
+ return LIS;
+ }
+}
+```
+
+```go
+func lengthOfLIS(nums []int) int {
+ n := len(nums)
+ memo := make([]int, n)
+ for i := range memo {
+ memo[i] = -1
+ }
+
+ var dfs func(int) int
+ dfs = func(i int) int {
+ if memo[i] != -1 {
+ return memo[i]
+ }
+
+ LIS := 1
+ for j := i + 1; j < n; j++ {
+ if nums[i] < nums[j] {
+ LIS = max(LIS, 1+dfs(j))
+ }
+ }
+
+ memo[i] = LIS
+ return LIS
+ }
+
+ maxLIS := 1
+ for i := 0; i < n; i++ {
+ maxLIS = max(maxLIS, dfs(i))
+ }
+
+ return maxLIS
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
+```kotlin
+class Solution {
+ private lateinit var memo: IntArray
+
+ fun lengthOfLIS(nums: IntArray): Int {
+ val n = nums.size
+ memo = IntArray(n) { -1 }
+
+ var maxLIS = 1
+ for (i in nums.indices) {
+ maxLIS = maxOf(maxLIS, dfs(nums, i))
+ }
+ return maxLIS
+ }
+
+ private fun dfs(nums: IntArray, i: Int): Int {
+ if (memo[i] != -1) {
+ return memo[i]
+ }
+
+ var LIS = 1
+ for (j in i + 1 until nums.size) {
+ if (nums[i] < nums[j]) {
+ LIS = maxOf(LIS, 1 + dfs(nums, j))
+ }
+ }
+
+ memo[i] = LIS
+ return LIS
+ }
+}
+```
+
+```swift
+class Solution {
+ func lengthOfLIS(_ nums: [Int]) -> Int {
+ let n = nums.count
+ var memo = Array(repeating: -1, count: n)
+
+ func dfs(_ i: Int) -> Int {
+ if memo[i] != -1 {
+ return memo[i]
+ }
+
+ var LIS = 1
+ for j in (i + 1)..= 0; i--) {
+ for (int j = i - 1; j >= -1; j--) {
+ int LIS = dp[i + 1][j + 1]; // Not including nums[i]
+
+ if (j == -1 || nums[j] < nums[i]) {
+ LIS = Math.max(LIS, 1 + dp[i + 1][i + 1]); // Including nums[i]
+ }
+
+ dp[i][j + 1] = LIS;
+ }
+ }
+
+ return dp[0][0];
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ int lengthOfLIS(vector& nums) {
+ int n = nums.size();
+ vector> dp(n + 1, vector(n + 1, 0));
+
+ for (int i = n - 1; i >= 0; --i) {
+ for (int j = i - 1; j >= -1; --j) {
+ int LIS = dp[i + 1][j + 1]; // Not including nums[i]
+
+ if (j == -1 || nums[j] < nums[i]) {
+ LIS = max(LIS, 1 + dp[i + 1][i + 1]); // Including nums[i]
+ }
+
+ dp[i][j + 1] = LIS;
+ }
+ }
+
+ return dp[0][0];
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} nums
+ * @return {number}
+ */
+ lengthOfLIS(nums) {
+ const n = nums.length;
+ const dp = Array.from({ length: n + 1 }, () => new Array(n + 1).fill(0));
+
+ for (let i = n - 1; i >= 0; i--) {
+ for (let j = i - 1; j >= -1; j--) {
+ let LIS = dp[i + 1][j + 1]; // Not including nums[i]
+
+ if (j === -1 || nums[j] < nums[i]) {
+ LIS = Math.max(LIS, 1 + dp[i + 1][i + 1]); // Including nums[i]
+ }
+
+ dp[i][j + 1] = LIS;
+ }
+ }
+
+ return dp[0][0];
+ }
+}
+```
+
+```csharp
+public class Solution {
+ public int LengthOfLIS(int[] nums) {
+ int n = nums.Length;
+ int[,] dp = new int[n + 1, n + 1];
+
+ for (int i = n - 1; i >= 0; i--) {
+ for (int j = i - 1; j >= -1; j--) {
+ int LIS = dp[i + 1, j + 1]; // Not including nums[i]
+
+ if (j == -1 || nums[j] < nums[i]) {
+ LIS = Math.Max(LIS, 1 + dp[i + 1, i + 1]); // Including nums[i]
+ }
+
+ dp[i, j + 1] = LIS;
+ }
+ }
+
+ return dp[0, 0];
+ }
+}
+```
+
+```go
+func lengthOfLIS(nums []int) int {
+ n := len(nums)
+ dp := make([][]int, n+1)
+ for i := range dp {
+ dp[i] = make([]int, n+1)
+ }
+
+ for i := n - 1; i >= 0; i-- {
+ for j := i - 1; j >= -1; j-- {
+ LIS := dp[i+1][j+1] // Not including nums[i]
+
+ if j == -1 || nums[j] < nums[i] {
+ LIS = max(LIS, 1+dp[i+1][i+1]) // Including nums[i]
+ }
+
+ dp[i][j+1] = LIS
+ }
+ }
+
+ return dp[0][0]
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
+```kotlin
+class Solution {
+ fun lengthOfLIS(nums: IntArray): Int {
+ val n = nums.size
+ val dp = Array(n + 1) { IntArray(n + 1) }
+
+ for (i in n - 1 downTo 0) {
+ for (j in i - 1 downTo -1) {
+ var LIS = dp[i + 1][j + 1] // Not including nums[i]
+
+ if (j == -1 || nums[j] < nums[i]) {
+ LIS = maxOf(LIS, 1 + dp[i + 1][i + 1]) // Including nums[i]
+ }
+
+ dp[i][j + 1] = LIS
+ }
+ }
+
+ return dp[0][0]
+ }
+}
+```
+
+```swift
+class Solution {
+ func lengthOfLIS(_ nums: [Int]) -> Int {
+ let n = nums.count
+ var dp = Array(repeating: Array(repeating: 0, count: n + 1), count: n + 1)
+
+ for i in stride(from: n - 1, through: 0, by: -1) {
+ for j in stride(from: i - 1, through: -1, by: -1) {
+ var LIS = dp[i + 1][j + 1] // Not including nums[i]
+
+ if j == -1 || nums[j] < nums[i] {
+ LIS = max(LIS, 1 + dp[i + 1][i + 1]) // Including nums[i]
+ }
+
+ dp[i][j + 1] = LIS
+ }
+ }
+
+ return dp[0][0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -419,7 +943,7 @@ class Solution {
---
-## 3. Dynamic Programming (Bottom-Up)
+## 5. Dynamic Programming (Bottom-Up) - II
::tabs-start
@@ -556,6 +1080,23 @@ class Solution {
}
```
+```swift
+class Solution {
+ func lengthOfLIS(_ nums: [Int]) -> Int {
+ var LIS = Array(repeating: 1, count: nums.count)
+
+ for i in stride(from: nums.count - 1, through: 0, by: -1) {
+ for j in (i + 1)..> 1
+ while j >= 1 {
+ tree[j] = max(tree[j << 1], tree[j << 1 | 1])
+ j >>= 1
+ }
+ }
+
+ func query(_ l: Int, _ r: Int) -> Int {
+ if l > r {
+ return 0
+ }
+ var res = Int.min
+ var l = l + n
+ var r = r + n + 1
+ while l < r {
+ if l & 1 == 1 {
+ res = max(res, tree[l])
+ l += 1
+ }
+ if r & 1 == 1 {
+ r -= 1
+ res = max(res, tree[r])
+ }
+ l >>= 1
+ r >>= 1
+ }
+ return res
+ }
+}
+
+class Solution {
+ func lengthOfLIS(_ nums: [Int]) -> Int {
+ func compress(_ arr: [Int]) -> [Int] {
+ let sortedArr = Array(Set(arr)).sorted()
+ return arr.map { sortedArr.firstIndex(of: $0)! }
+ }
+
+ let nums = compress(nums)
+ let n = nums.count
+ let segTree = SegmentTree(n)
+
+ var LIS = 0
+ for num in nums {
+ let curLIS = segTree.query(0, num - 1) + 1
+ segTree.update(num, curLIS)
+ LIS = max(LIS, curLIS)
+ }
+ return LIS
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1059,7 +1667,7 @@ class Solution {
---
-## 5. Binary Search
+## 7. Dynamic Programming + Binary Search
::tabs-start
@@ -1237,6 +1845,39 @@ class Solution {
}
```
+```swift
+class Solution {
+ func lengthOfLIS(_ nums: [Int]) -> Int {
+ var dp = [nums[0]]
+ var LIS = 1
+
+ for i in 1.. Int {
+ var left = 0, right = dp.count - 1
+ while left < right {
+ let mid = (left + right) / 2
+ if dp[mid] < target {
+ left = mid + 1
+ } else {
+ right = mid
+ }
+ }
+ return left
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/longest-palindromic-substring.md b/articles/longest-palindromic-substring.md
index 715d7c512..1d0f82c17 100644
--- a/articles/longest-palindromic-substring.md
+++ b/articles/longest-palindromic-substring.md
@@ -180,12 +180,38 @@ class Solution {
}
```
+```swift
+class Solution {
+ func longestPalindrome(_ s: String) -> String {
+ let chars = Array(s)
+ var res = ""
+ var resLen = 0
+
+ for i in 0..= r && resLen < (j - i + 1) {
+ res = String(chars[i...j])
+ resLen = j - i + 1
+ }
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(n ^ 3)$
-* Space complexity: $O(1)$
+* Space complexity: $O(n)$
---
@@ -377,6 +403,31 @@ class Solution {
}
```
+```swift
+class Solution {
+ func longestPalindrome(_ s: String) -> String {
+ let chars = Array(s)
+ let n = chars.count
+ var resIdx = 0, resLen = 0
+ var dp = Array(repeating: Array(repeating: false, count: n), count: n)
+
+ for i in stride(from: n - 1, through: 0, by: -1) {
+ for j in i.. String {
+ let chars = Array(s)
+ var resIdx = 0
+ var resLen = 0
+
+ for i in 0..= 0 && r < chars.count && chars[l] == chars[r] {
+ if (r - l + 1) > resLen {
+ resIdx = l
+ resLen = r - l + 1
+ }
+ l -= 1
+ r += 1
+ }
+
+ // Even length palindrome
+ l = i
+ r = i + 1
+ while l >= 0 && r < chars.count && chars[l] == chars[r] {
+ if (r - l + 1) > resLen {
+ resIdx = l
+ resLen = r - l + 1
+ }
+ l -= 1
+ r += 1
+ }
+ }
+
+ return String(chars[resIdx.. String {
+ func manacher(_ s: String) -> [Int] {
+ let t = "#" + s.map { String($0) }.joined(separator: "#") + "#"
+ let tArray = Array(t)
+ let n = tArray.count
+ var p = [Int](repeating: 0, count: n)
+ var l = 0, r = 0
+
+ for i in 0..= 0 &&
+ tArray[i + p[i] + 1] == tArray[i - p[i] - 1]) {
+ p[i] += 1
+ }
+ if i + p[i] > r {
+ l = i - p[i]
+ r = i + p[i]
+ }
+ }
+ return p
+ }
+
+ let p = manacher(s)
+ var resLen = 0, centerIndex = 0
+ for (i, v) in p.enumerated() {
+ if v > resLen {
+ resLen = v
+ centerIndex = i
+ }
+ }
+ let resIdx = (centerIndex - resLen) / 2
+ let start = s.index(s.startIndex, offsetBy: resIdx)
+ let end = s.index(start, offsetBy: resLen)
+ return String(s[start.. Int {
+ var res = 0
+ let chars = Array(s)
+
+ for i in 0.. Int {
+ var res = 0
+ let charSet = Set(s)
+ let chars = Array(s)
+
+ for c in charSet {
+ var count = 0, l = 0
+
+ for r in 0.. k {
+ if chars[l] == c {
+ count -= 1
+ }
+ l += 1
+ }
+
+ res = max(res, r - l + 1)
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -563,6 +617,30 @@ class Solution {
}
```
+```swift
+class Solution {
+ func characterReplacement(_ s: String, _ k: Int) -> Int {
+ var count = [Character: Int]()
+ var res = 0
+ var l = 0, maxf = 0
+ let chars = Array(s)
+
+ for r in 0.. k {
+ count[chars[l], default: 0] -= 1
+ l += 1
+ }
+ res = max(res, r - l + 1)
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/longest-substring-without-duplicates.md b/articles/longest-substring-without-duplicates.md
index a37747ed3..3d197dc21 100644
--- a/articles/longest-substring-without-duplicates.md
+++ b/articles/longest-substring-without-duplicates.md
@@ -137,6 +137,27 @@ class Solution {
}
```
+```kotlin
+class Solution {
+ func lengthOfLongestSubstring(_ s: String) -> Int {
+ var res = 0
+ let chars = Array(s)
+
+ for i in 0..()
+ for j in i.. Int {
+ var charSet = Set()
+ var l = 0, res = 0
+ let chars = Array(s)
+
+ for r in 0.. Int {
+ var mp = [Character: Int]()
+ var l = 0, res = 0
+ let chars = Array(s)
+
+ for r in 0.. TreeNode? {
+ guard let root = root, let p = p, let q = q else {
+ return nil
+ }
+
+ if max(p.val, q.val) < root.val {
+ return lowestCommonAncestor(root.left, p, q)
+ } else if min(p.val, q.val) > root.val {
+ return lowestCommonAncestor(root.right, p, q)
+ } else {
+ return root
+ }
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -436,6 +468,41 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init(_ val: Int) {
+ * self.val = val
+ * self.left = nil
+ * self.right = nil
+ * }
+ * }
+ */
+
+class Solution {
+ func lowestCommonAncestor(_ root: TreeNode?, _ p: TreeNode?, _ q: TreeNode?) -> TreeNode? {
+ var cur = root
+
+ while let node = cur {
+ if let p = p, let q = q {
+ if p.val > node.val && q.val > node.val {
+ cur = node.right
+ } else if p.val < node.val && q.val < node.val {
+ cur = node.left
+ } else {
+ return node
+ }
+ }
+ }
+ return nil
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/lru-cache.md b/articles/lru-cache.md
index d93c79886..2bd939f9c 100644
--- a/articles/lru-cache.md
+++ b/articles/lru-cache.md
@@ -279,6 +279,46 @@ class LRUCache(capacity: Int) {
}
```
+```swift
+class LRUCache {
+ private var cache: [(Int, Int)]
+ private let capacity: Int
+
+ init(_ capacity: Int) {
+ self.cache = []
+ self.capacity = capacity
+ }
+
+ func get(_ key: Int) -> Int {
+ for i in 0.. Int {
+ if let node = cache[key] {
+ remove(node)
+ insert(node)
+ return node.val
+ }
+ return -1
+ }
+
+ func put(_ key: Int, _ value: Int) {
+ if let node = cache[key] {
+ remove(node)
+ }
+ let newNode = Node(key, value)
+ cache[key] = newNode
+ insert(newNode)
+
+ if cache.count > cap {
+ if let lru = left.next {
+ remove(lru)
+ cache.removeValue(forKey: lru.key)
+ }
+ }
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1002,6 +1112,45 @@ class LRUCache(capacity: Int) {
}
```
+```swift
+class LRUCache {
+ private var capacity: Int
+ private var cache: [Int: Int] = [:]
+ private var keyOrder: [Int] = []
+
+ init(_ capacity: Int) {
+ self.capacity = capacity
+ }
+
+ func get(_ key: Int) -> Int {
+ if let value = cache[key] {
+ if let index = keyOrder.firstIndex(of: key) {
+ keyOrder.remove(at: index)
+ }
+ keyOrder.append(key)
+ return value
+ }
+ return -1
+ }
+
+ func put(_ key: Int, _ value: Int) {
+ if cache[key] != nil {
+ if let index = keyOrder.firstIndex(of: key) {
+ keyOrder.remove(at: index)
+ }
+ } else if cache.count >= capacity {
+ if let lruKey = keyOrder.first {
+ cache.removeValue(forKey: lruKey)
+ keyOrder.removeFirst()
+ }
+ }
+
+ cache[key] = value
+ keyOrder.append(key)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/max-area-of-island.md b/articles/max-area-of-island.md
index 22f9f8b53..cb69ca56d 100644
--- a/articles/max-area-of-island.md
+++ b/articles/max-area-of-island.md
@@ -232,6 +232,34 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxAreaOfIsland(_ grid: [[Int]]) -> Int {
+ let ROWS = grid.count
+ let COLS = grid[0].count
+ var visit = Set<[Int]>()
+ var grid = grid
+
+ func dfs(_ r: Int, _ c: Int) -> Int {
+ if (r < 0 || r == ROWS || c < 0 || c == COLS ||
+ grid[r][c] == 0 || visit.contains([r, c])) {
+ return 0
+ }
+ visit.insert([r, c])
+ return 1 + dfs(r + 1, c) + dfs(r - 1, c) + dfs(r, c + 1) + dfs(r, c - 1)
+ }
+
+ var area = 0
+ for r in 0.. Int {
+ let directions = [[1, 0], [-1, 0], [0, 1], [0, -1]]
+ let ROWS = grid.count
+ let COLS = grid[0].count
+ var grid = grid
+ var area = 0
+
+ func bfs(_ r: Int, _ c: Int) -> Int {
+ var queue = Deque<(Int, Int)>()
+ grid[r][c] = 0
+ queue.append((r, c))
+ var res = 1
+
+ while !queue.isEmpty {
+ let (row, col) = queue.popFirst()!
+ for dir in directions {
+ let nr = row + dir[0]
+ let nc = col + dir[1]
+ if nr < 0 || nc < 0 || nr >= ROWS || nc >= COLS || grid[nr][nc] == 0 {
+ continue
+ }
+ queue.append((nr, nc))
+ grid[nr][nc] = 0
+ res += 1
+ }
+ }
+ return res
+ }
+
+ for r in 0.. Int {
+ if parent[node] != node {
+ parent[node] = find(parent[node])
+ }
+ return parent[node]
+ }
+
+ func union(_ u: Int, _ v: Int) -> Bool {
+ let pu = find(u)
+ let pv = find(v)
+ if pu == pv {
+ return false
+ }
+ if size[pu] >= size[pv] {
+ size[pu] += size[pv]
+ parent[pv] = pu
+ } else {
+ size[pv] += size[pu]
+ parent[pu] = pv
+ }
+ return true
+ }
+
+ func getSize(_ node: Int) -> Int {
+ let par = find(node)
+ return size[par]
+ }
+}
+
+class Solution {
+ func maxAreaOfIsland(_ grid: [[Int]]) -> Int {
+ var grid = grid
+ let ROWS = grid.count
+ let COLS = grid[0].count
+ let dsu = DSU(ROWS * COLS)
+
+ func index(_ r: Int, _ c: Int) -> Int {
+ return r * COLS + c
+ }
+
+ let directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
+ var area = 0
+
+ for r in 0..= ROWS || nc >= COLS || grid[nr][nc] == 0 {
+ continue
+ }
+ dsu.union(index(r, c), index(nr, nc))
+ }
+ area = max(area, dsu.getSize(index(r, c)))
+ }
+ }
+ }
+
+ return area
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/max-water-container.md b/articles/max-water-container.md
index dfd046f07..bb1ea6083 100644
--- a/articles/max-water-container.md
+++ b/articles/max-water-container.md
@@ -110,6 +110,20 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxArea(_ heights: [Int]) -> Int {
+ var res = 0
+ for i in 0.. Int {
+ var l = 0, r = heights.count - 1
+ var res = 0
+
+ while l < r {
+ let area = min(heights[l], heights[r]) * (r - l)
+ res = max(res, area)
+ if heights[l] <= heights[r] {
+ l += 1
+ } else {
+ r -= 1
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/maximum-product-subarray.md b/articles/maximum-product-subarray.md
index 5f5f0e299..f163b341f 100644
--- a/articles/maximum-product-subarray.md
+++ b/articles/maximum-product-subarray.md
@@ -137,6 +137,25 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxProduct(_ nums: [Int]) -> Int {
+ var res = nums[0]
+
+ for i in 0.. Int {
+ var A = [[Int]]()
+ var cur = [Int]()
+ var res = Int.min
+
+ for num in nums {
+ res = max(res, num)
+ if num == 0 {
+ if !cur.isEmpty {
+ A.append(cur)
+ }
+ cur = []
+ } else {
+ cur.append(num)
+ }
+ }
+
+ if !cur.isEmpty {
+ A.append(cur)
+ }
+
+ for sub in A {
+ let negsCount = sub.filter { $0 < 0 }.count
+ var prod = 1
+ var need = negsCount % 2 == 0 ? negsCount : negsCount - 1
+ var negs = 0
+ var j = 0
+
+ for i in 0.. need {
+ prod /= sub[j]
+ if sub[j] < 0 {
+ negs -= 1
+ }
+ j += 1
+ }
+ }
+ if j <= i {
+ res = max(res, prod)
+ }
+ }
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -642,6 +714,23 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxProduct(_ nums: [Int]) -> Int {
+ var res = nums[0]
+ var curMin = 1, curMax = 1
+
+ for num in nums {
+ let tmp = curMax * num
+ curMax = max(num * curMax, num * curMin, num)
+ curMin = min(tmp, num * curMin, num)
+ res = max(res, curMax)
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -791,6 +880,23 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxProduct(_ nums: [Int]) -> Int {
+ let n = nums.count
+ var res = nums[0]
+ var prefix = 0, suffix = 0
+
+ for i in 0.. Int {
+ let n = nums.count
+ var res = nums[0]
+
+ for i in 0.. Int {
+ func dfs(_ i: Int, _ flag: Bool) -> Int {
+ if i == nums.count {
+ return flag ? 0 : Int.min
+ }
+
+ if flag {
+ return max(0, nums[i] + dfs(i + 1, true))
+ }
+
+ return max(dfs(i + 1, false), nums[i] + dfs(i + 1, true))
+ }
+
+ return dfs(0, false)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -449,6 +488,33 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxSubArray(_ nums: [Int]) -> Int {
+ var memo = Array(repeating: [Int?](repeating: nil, count: 2), count: nums.count + 1)
+
+ func dfs(_ i: Int, _ flag: Bool) -> Int {
+ if i == nums.count {
+ return flag ? 0 : Int.min
+ }
+ if let value = memo[i][flag ? 1 : 0] {
+ return value
+ }
+
+ if flag {
+ memo[i][flag ? 1 : 0] = max(0, nums[i] + dfs(i + 1, true))
+ } else {
+ memo[i][flag ? 1 : 0] = max(dfs(i + 1, false), nums[i] + dfs(i + 1, true))
+ }
+
+ return memo[i][flag ? 1 : 0]!
+ }
+
+ return dfs(0, false)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -594,6 +660,24 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxSubArray(_ nums: [Int]) -> Int {
+ let n = nums.count
+ var dp = Array(repeating: [0, 0], count: n)
+ dp[n - 1][1] = nums[n - 1]
+ dp[n - 1][0] = nums[n - 1]
+
+ for i in (0.. Int {
+ var dp = nums
+
+ for i in 1.. Int {
+ var maxSub = nums[0]
+ var curSum = 0
+
+ for num in nums {
+ if curSum < 0 {
+ curSum = 0
+ }
+ curSum += num
+ maxSub = max(maxSub, curSum)
+ }
+
+ return maxSub
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1092,6 +1209,39 @@ class Solution {
}
```
+```swift
+class Solution {
+ func maxSubArray(_ nums: [Int]) -> Int {
+
+ func dfs(_ l: Int, _ r: Int) -> Int {
+ if l > r {
+ return Int.min
+ }
+
+ let m = (l + r) / 2
+ var leftSum = 0
+ var rightSum = 0
+ var curSum = 0
+
+ for i in stride(from: m - 1, through: l, by: -1) {
+ curSum += nums[i]
+ leftSum = max(leftSum, curSum)
+ }
+
+ curSum = 0
+ for i in stride(from: m + 1, to: r + 1, by: 1) {
+ curSum += nums[i]
+ rightSum = max(rightSum, curSum)
+ }
+
+ return max(dfs(l, m - 1), dfs(m + 1, r), leftSum + nums[m] + rightSum)
+ }
+
+ return dfs(0, nums.count - 1)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/median-of-two-sorted-arrays.md b/articles/median-of-two-sorted-arrays.md
index 6fb01b6af..3ac051111 100644
--- a/articles/median-of-two-sorted-arrays.md
+++ b/articles/median-of-two-sorted-arrays.md
@@ -127,6 +127,22 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findMedianSortedArrays(_ nums1: [Int], _ nums2: [Int]) -> Double {
+ var merged = nums1 + nums2
+ merged.sort()
+
+ let totalLen = merged.count
+ if totalLen % 2 == 0 {
+ return (Double(merged[totalLen / 2 - 1]) + Double(merged[totalLen / 2])) / 2.0
+ } else {
+ return Double(merged[totalLen / 2])
+ }
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -391,6 +407,41 @@ class Solution {
}
```
+```kotlin
+class Solution {
+ func findMedianSortedArrays(_ nums1: [Int], _ nums2: [Int]) -> Double {
+ let len1 = nums1.count, len2 = nums2.count
+ var i = 0, j = 0
+ var median1 = 0, median2 = 0
+
+ for _ in 0..<(len1 + len2) / 2 + 1 {
+ median2 = median1
+ if i < len1 && j < len2 {
+ if nums1[i] > nums2[j] {
+ median1 = nums2[j]
+ j += 1
+ } else {
+ median1 = nums1[i]
+ i += 1
+ }
+ } else if i < len1 {
+ median1 = nums1[i]
+ i += 1
+ } else {
+ median1 = nums2[j]
+ j += 1
+ }
+ }
+
+ if (len1 + len2) % 2 == 1 {
+ return Double(median1)
+ } else {
+ return (Double(median1) + Double(median2)) / 2.0
+ }
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -653,12 +704,44 @@ class Solution {
}
```
+```swift
+class Solution {
+ func getKth(_ a: [Int], _ m: Int, _ b: [Int], _ n: Int, _ k: Int, _ aStart: Int = 0, _ bStart: Int = 0) -> Int {
+ if m > n {
+ return getKth(b, n, a, m, k, bStart, aStart)
+ }
+ if m == 0 {
+ return b[bStart + k - 1]
+ }
+ if k == 1 {
+ return min(a[aStart], b[bStart])
+ }
+
+ let i = min(m, k / 2)
+ let j = min(n, k / 2)
+
+ if a[aStart + i - 1] > b[bStart + j - 1] {
+ return getKth(a, m, b, n - j, k - j, aStart, bStart + j)
+ } else {
+ return getKth(a, m - i, b, n, k - i, aStart + i, bStart)
+ }
+ }
+
+ func findMedianSortedArrays(_ nums1: [Int], _ nums2: [Int]) -> Double {
+ let left = (nums1.count + nums2.count + 1) / 2
+ let right = (nums1.count + nums2.count + 2) / 2
+ return (Double(getKth(nums1, nums1.count, nums2, nums2.count, left)) +
+ Double(getKth(nums1, nums1.count, nums2, nums2.count, right))) / 2.0
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(\log (m + n))$
-* Space complexity: $O(\log (m + n))$
+* Space complexity: $O(\log (m + n))$ for recursion stack.
> Where $n$ is the length of $nums1$ and $m$ is the length of $nums2$.
@@ -969,6 +1052,44 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findMedianSortedArrays(_ nums1: [Int], _ nums2: [Int]) -> Double {
+ var A = nums1, B = nums2
+ if A.count > B.count {
+ swap(&A, &B)
+ }
+
+ let total = A.count + B.count
+ let half = total / 2
+ var l = 0
+ var r = A.count
+
+ while true {
+ let i = (l + r) / 2
+ let j = half - i
+
+ let Aleft = i > 0 ? Double(A[i - 1]) : -Double.infinity
+ let Aright = i < A.count ? Double(A[i]) : Double.infinity
+ let Bleft = j > 0 ? Double(B[j - 1]) : -Double.infinity
+ let Bright = j < B.count ? Double(B[j]) : Double.infinity
+
+ if Aleft <= Bright && Bleft <= Aright {
+ if total % 2 == 1 {
+ return min(Aright, Bright)
+ } else {
+ return (max(Aleft, Bleft) + min(Aright, Bright)) / 2.0
+ }
+ } else if Aleft > Bright {
+ r = i - 1
+ } else {
+ l = i + 1
+ }
+ }
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/meeting-schedule-ii.md b/articles/meeting-schedule-ii.md
index ce53b1e92..afd50a48e 100644
--- a/articles/meeting-schedule-ii.md
+++ b/articles/meeting-schedule-ii.md
@@ -193,6 +193,34 @@ class Solution {
}
```
+```swift
+/**
+ * Definition of Interval:
+ * class Interval {
+ * var start: Int
+ * var end: Int
+ * init(start: Int, end: Int) {
+ * self.start = start
+ * self.end = end
+ * }
+ * }
+ */
+
+class Solution {
+ func minMeetingRooms(_ intervals: [Interval]) -> Int {
+ let sortedIntervals = intervals.sorted { $0.start < $1.start }
+ var minHeap = Heap()
+ for interval in sortedIntervals {
+ if !minHeap.isEmpty, let earliest = minHeap.min!, earliest <= interval.start {
+ minHeap.removeMin()
+ }
+ minHeap.insert(interval.end)
+ }
+ return minHeap.count
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -414,6 +442,37 @@ class Solution {
}
```
+```swift
+/**
+ * Definition of Interval:
+ * class Interval {
+ * var start: Int
+ * var end: Int
+ * init(start: Int, end: Int) {
+ * self.start = start
+ * self.end = end
+ * }
+ * }
+ */
+
+class Solution {
+ func minMeetingRooms(_ intervals: [Interval]) -> Int {
+ var mp = [Int: Int]()
+ for interval in intervals {
+ mp[interval.start, default: 0] += 1
+ mp[interval.end, default: 0] -= 1
+ }
+ var prev = 0
+ var res = 0
+ for key in mp.keys.sorted() {
+ prev += mp[key]!
+ res = max(res, prev)
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -689,6 +748,40 @@ class Solution {
}
```
+```swift
+/**
+ * Definition of Interval:
+ * class Interval {
+ * var start: Int
+ * var end: Int
+ * init(start: Int, end: Int) {
+ * self.start = start
+ * self.end = end
+ * }
+ * }
+ */
+
+class Solution {
+ func minMeetingRooms(_ intervals: [Interval]) -> Int {
+ let starts = intervals.map { $0.start }.sorted()
+ let ends = intervals.map { $0.end }.sorted()
+
+ var res = 0, count = 0, s = 0, e = 0
+ while s < intervals.count {
+ if starts[s] < ends[e] {
+ count += 1
+ s += 1
+ } else {
+ count -= 1
+ e += 1
+ }
+ res = max(res, count)
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -929,6 +1022,47 @@ class Solution {
}
```
+```swift
+/**
+ * Definition of Interval:
+ * class Interval {
+ * var start: Int
+ * var end: Int
+ * init(start: Int, end: Int) {
+ * self.start = start
+ * self.end = end
+ * }
+ * }
+ */
+
+class Solution {
+ func minMeetingRooms(_ intervals: [Interval]) -> Int {
+ var times = [(Int, Int)]()
+ for interval in intervals {
+ times.append((interval.start, 1))
+ times.append((interval.end, -1))
+ }
+
+ times.sort {
+ if $0.0 != $1.0 {
+ return $0.0 < $1.0
+ } else {
+ return $0.1 < $1.1
+ }
+ }
+
+ var count = 0
+ var res = 0
+ for t in times {
+ count += t.1
+ res = max(res, count)
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/meeting-schedule.md b/articles/meeting-schedule.md
index 735df876a..226a6a70f 100644
--- a/articles/meeting-schedule.md
+++ b/articles/meeting-schedule.md
@@ -205,6 +205,36 @@ class Solution {
}
```
+```swift
+/**
+ * Definition of Interval:
+ * class Interval {
+ * var start: Int
+ * var end: Int
+ * init(start: Int, end: Int) {
+ * self.start = start
+ * self.end = end
+ * }
+ * }
+ */
+
+class Solution {
+ func canAttendMeetings(_ intervals: [Interval]) -> Bool {
+ let n = intervals.count
+ for i in 0.. max(A.start, B.start) {
+ return false
+ }
+ }
+ }
+ return true
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -400,6 +430,32 @@ class Solution {
}
```
+```swift
+/**
+ * Definition of Interval:
+ * class Interval {
+ * var start: Int
+ * var end: Int
+ * init(start: Int, end: Int) {
+ * self.start = start
+ * self.end = end
+ * }
+ * }
+ */
+
+class Solution {
+ func canAttendMeetings(_ intervals: [Interval]) -> Bool {
+ let sortedIntervals = intervals.sorted { $0.start < $1.start }
+ for i in 1.. sortedIntervals[i].start {
+ return false
+ }
+ }
+ return true
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/merge-intervals.md b/articles/merge-intervals.md
index 4ff97b569..100d894b6 100644
--- a/articles/merge-intervals.md
+++ b/articles/merge-intervals.md
@@ -164,6 +164,28 @@ class Solution {
}
```
+```swift
+class Solution {
+ func merge(_ intervals: [[Int]]) -> [[Int]] {
+ let intervals = intervals.sorted { $0[0] < $1[0] }
+ var output: [[Int]] = [intervals[0]]
+
+ for interval in intervals {
+ let start = interval[0]
+ let end = interval[1]
+ var lastEnd = output.last![1]
+
+ if start <= lastEnd {
+ output[output.count - 1][1] = max(lastEnd, end)
+ } else {
+ output.append([start, end])
+ }
+ }
+ return output
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -383,6 +405,38 @@ class Solution {
}
```
+```swift
+class Solution {
+ func merge(_ intervals: [[Int]]) -> [[Int]] {
+ var mp = [Int: Int]()
+
+ for interval in intervals {
+ let start = interval[0]
+ let end = interval[1]
+ mp[start, default: 0] += 1
+ mp[end, default: 0] -= 1
+ }
+
+ var res = [[Int]]()
+ var interval = [Int]()
+ var have = 0
+
+ for i in mp.keys.sorted() {
+ if interval.isEmpty {
+ interval.append(i)
+ }
+ have += mp[i, default: 0]
+ if have == 0 {
+ interval.append(i)
+ res.append(interval)
+ interval = []
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -678,6 +732,44 @@ class Solution {
}
```
+```swift
+class Solution {
+ func merge(_ intervals: [[Int]]) -> [[Int]] {
+ let maxVal = intervals.map { $0[0] }.max() ?? 0
+ var mp = [Int](repeating: 0, count: maxVal + 1)
+ for interval in intervals {
+ let start = interval[0]
+ let end = interval[1]
+ mp[start] = max(end + 1, mp[start])
+ }
+
+ var res = [[Int]]()
+ var have = -1
+ var intervalStart = -1
+
+ for i in 0.. ListNode? {
+ var nodes: [Int] = []
+
+ for list in lists {
+ var lst = list
+ while lst != nil {
+ nodes.append(lst!.val)
+ lst = lst?.next
+ }
+ }
+
+ nodes.sort()
+
+ let dummy = ListNode(0)
+ var cur = dummy
+ for node in nodes {
+ cur.next = ListNode(node)
+ cur = cur.next!
+ }
+
+ return dummy.next
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -510,6 +547,47 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func mergeKLists(_ lists: [ListNode?]) -> ListNode? {
+ var lists = lists
+ let dummy = ListNode(0)
+ var cur = dummy
+
+ while true {
+ var minNodeIndex: Int? = nil
+ for i in 0.. ListNode? {
+ if lists.isEmpty {
+ return nil
+ }
+
+ var lists = lists
+ for i in 1.. ListNode? {
+ let dummy = ListNode(0)
+ var tail = dummy
+ var l1 = l1, l2 = l2
+
+ while l1 != nil && l2 != nil {
+ if l1!.val < l2!.val {
+ tail.next = l1
+ l1 = l1?.next
+ } else {
+ tail.next = l2
+ l2 = l2?.next
+ }
+ tail = tail.next!
+ }
+
+ if l1 != nil {
+ tail.next = l1
+ }
+ if l2 != nil {
+ tail.next = l2
+ }
+
+ return dummy.next
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1157,6 +1288,60 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+struct NodeWrapper: Comparable {
+ let node: ListNode
+
+ init(_ node: ListNode) {
+ self.node = node
+ }
+
+ static func < (lhs: NodeWrapper, rhs: NodeWrapper) -> Bool {
+ return lhs.node.val < rhs.node.val
+ }
+
+ static func == (lhs: NodeWrapper, rhs: NodeWrapper) -> Bool {
+ return lhs.node.val == rhs.node.val
+ }
+}
+
+class Solution {
+ func mergeKLists(_ lists: [ListNode?]) -> ListNode? {
+ var heap = Heap()
+
+ for list in lists {
+ if let node = list {
+ heap.insert(NodeWrapper(node))
+ }
+ }
+
+ let dummy = ListNode(0)
+ var tail = dummy
+
+ while let wrapper = heap.popMin() {
+ tail.next = wrapper.node
+ tail = tail.next!
+
+ if let next = wrapper.node.next {
+ heap.insert(NodeWrapper(next))
+ }
+ }
+
+ return dummy.next
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1190,14 +1375,17 @@ class Solution:
return None
if l == r:
return lists[l]
+
mid = l + (r - l) // 2
left = self.divide(lists, l, mid)
right = self.divide(lists, mid + 1, r)
+
return self.conquer(left, right)
def conquer(self, l1, l2):
dummy = ListNode(0)
curr = dummy
+
while l1 and l2:
if l1.val <= l2.val:
curr.next = l1
@@ -1206,10 +1394,12 @@ class Solution:
curr.next = l2
l2 = l2.next
curr = curr.next
+
if l1:
curr.next = l1
else:
curr.next = l2
+
return dummy.next
```
@@ -1240,9 +1430,11 @@ class Solution {
if (l == r) {
return lists[l];
}
+
int mid = l + (r - l) / 2;
ListNode left = divide(lists, l, mid);
ListNode right = divide(lists, mid + 1, r);
+
return conquer(left, right);
}
@@ -1302,15 +1494,18 @@ private:
if (l == r) {
return lists[l];
}
+
int mid = l + (r - l) / 2;
ListNode* left = divide(lists, l, mid);
ListNode* right = divide(lists, mid + 1, r);
+
return conquer(left, right);
}
ListNode* conquer(ListNode* l1, ListNode* l2) {
ListNode dummy(0);
ListNode* curr = &dummy;
+
while (l1 && l2) {
if (l1->val <= l2->val) {
curr->next = l1;
@@ -1321,11 +1516,13 @@ private:
}
curr = curr->next;
}
+
if (l1) {
curr->next = l1;
} else {
curr->next = l2;
}
+
return dummy.next;
}
};
@@ -1367,9 +1564,11 @@ class Solution {
if (l === r) {
return lists[l];
}
+
const mid = Math.floor(l + (r - l) / 2);
const left = this.divide(lists, l, mid);
const right = this.divide(lists, mid + 1, r);
+
return this.conquer(left, right);
}
@@ -1381,6 +1580,7 @@ class Solution {
conquer(l1, l2) {
const dummy = new ListNode(0);
let curr = dummy;
+
while (l1 && l2) {
if (l1.val <= l2.val) {
curr.next = l1;
@@ -1391,6 +1591,7 @@ class Solution {
}
curr = curr.next;
}
+
curr.next = l1 ? l1 : l2;
return dummy.next;
}
@@ -1425,9 +1626,11 @@ public class Solution {
if (l == r) {
return lists[l];
}
+
int mid = l + (r - l) / 2;
ListNode left = Divide(lists, l, mid);
ListNode right = Divide(lists, mid + 1, r);
+
return Conquer(left, right);
}
@@ -1479,15 +1682,18 @@ func divide(lists []*ListNode, left, right int) *ListNode {
if left == right {
return lists[left]
}
+
mid := left + (right-left)/2
l1 := divide(lists, left, mid)
l2 := divide(lists, mid+1, right)
+
return conquer(l1, l2)
}
func conquer(l1, l2 *ListNode) *ListNode {
dummy := &ListNode{}
curr := dummy
+
for l1 != nil && l2 != nil {
if l1.Val <= l2.Val {
curr.Next = l1
@@ -1498,11 +1704,13 @@ func conquer(l1, l2 *ListNode) *ListNode {
}
curr = curr.Next
}
+
if l1 != nil {
curr.Next = l1
} else {
curr.Next = l2
}
+
return dummy.Next
}
```
@@ -1526,9 +1734,11 @@ class Solution {
private fun divide(lists: Array, left: Int, right: Int): ListNode? {
if (left > right) return null
if (left == right) return lists[left]
+
val mid = left + (right - left) / 2
val l1 = divide(lists, left, mid)
val l2 = divide(lists, mid + 1, right)
+
return conquer(l1, l2)
}
@@ -1537,6 +1747,7 @@ class Solution {
var curr = dummy
var list1 = l1
var list2 = l2
+
while (list1 != null && list2 != null) {
if (list1.`val` <= list2.`val`) {
curr.next = list1
@@ -1547,12 +1758,68 @@ class Solution {
}
curr = curr.next!!
}
+
curr.next = list1 ?: list2
return dummy.next
}
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func mergeKLists(_ lists: [ListNode?]) -> ListNode? {
+ if lists.isEmpty {
+ return nil
+ }
+ return divide(lists, 0, lists.count - 1)
+ }
+
+ private func divide(_ lists: [ListNode?], _ l: Int, _ r: Int) -> ListNode? {
+ if l > r {
+ return nil
+ }
+ if l == r {
+ return lists[l]
+ }
+
+ let mid = l + (r - l) / 2
+ let left = divide(lists, l, mid)
+ let right = divide(lists, mid + 1, r)
+ return conquer(left, right)
+ }
+
+ private func conquer(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
+ let dummy = ListNode(0)
+ var curr = dummy
+ var l1 = l1, l2 = l2
+
+ while let node1 = l1, let node2 = l2 {
+ if node1.val <= node2.val {
+ curr.next = node1
+ l1 = node1.next
+ } else {
+ curr.next = node2
+ l2 = node2.next
+ }
+ curr = curr.next!
+ }
+
+ curr.next = l1 ?? l2
+ return dummy.next
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1602,10 +1869,12 @@ class Solution:
tail.next = l2
l2 = l2.next
tail = tail.next
+
if l1:
tail.next = l1
if l2:
tail.next = l2
+
return dummy.next
```
@@ -1653,12 +1922,14 @@ public class Solution {
}
tail = tail.next;
}
+
if (l1 != null) {
tail.next = l1;
}
if (l2 != null) {
tail.next = l2;
}
+
return dummy.next;
}
}
@@ -1710,12 +1981,14 @@ private:
}
tail = tail->next;
}
+
if (l1) {
tail->next = l1;
}
if (l2) {
tail->next = l2;
}
+
return dummy.next;
}
};
@@ -1762,6 +2035,7 @@ class Solution {
mergeList(l1, l2) {
const dummy = new ListNode(0);
let curr = dummy;
+
while (l1 && l2) {
if (l1.val <= l2.val) {
curr.next = l1;
@@ -1772,6 +2046,7 @@ class Solution {
}
curr = curr.next;
}
+
curr.next = l1 ? l1 : l2;
return dummy.next;
}
@@ -1823,12 +2098,14 @@ public class Solution {
}
tail = tail.next;
}
+
if (l1 != null) {
tail.next = l1;
}
if (l2 != null) {
tail.next = l2;
}
+
return dummy.next;
}
}
@@ -1876,11 +2153,13 @@ func mergeList(l1, l2 *ListNode) *ListNode {
}
tail = tail.Next
}
+
if l1 != nil {
tail.Next = l1
} else {
tail.Next = l2
}
+
return dummy.Next
}
```
@@ -1928,12 +2207,69 @@ class Solution {
}
tail = tail.next!!
}
+
tail.next = list1 ?: list2
return dummy.next
}
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func mergeKLists(_ lists: [ListNode?]) -> ListNode? {
+ if lists.isEmpty {
+ return nil
+ }
+
+ var lists = lists
+
+ while lists.count > 1 {
+ var mergedLists: [ListNode?] = []
+
+ for i in stride(from: 0, to: lists.count, by: 2) {
+ let l1 = lists[i]
+ let l2 = i + 1 < lists.count ? lists[i + 1] : nil
+ mergedLists.append(mergeList(l1, l2))
+ }
+
+ lists = mergedLists
+ }
+
+ return lists[0]
+ }
+
+ private func mergeList(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
+ let dummy = ListNode(0)
+ var tail = dummy
+ var l1 = l1, l2 = l2
+
+ while let node1 = l1, let node2 = l2 {
+ if node1.val < node2.val {
+ tail.next = node1
+ l1 = node1.next
+ } else {
+ tail.next = node2
+ l2 = node2.next
+ }
+ tail = tail.next!
+ }
+
+ tail.next = l1 ?? l2
+ return dummy.next
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/merge-triplets-to-form-target.md b/articles/merge-triplets-to-form-target.md
index 4fe080b4c..268d8ae9d 100644
--- a/articles/merge-triplets-to-form-target.md
+++ b/articles/merge-triplets-to-form-target.md
@@ -138,6 +138,27 @@ class Solution {
}
```
+```swift
+class Solution {
+ func mergeTriplets(_ triplets: [[Int]], _ target: [Int]) -> Bool {
+ var good = Set()
+
+ for t in triplets {
+ if t[0] > target[0] || t[1] > target[1] || t[2] > target[2] {
+ continue
+ }
+ for (i, v) in t.enumerated() {
+ if v == target[i] {
+ good.insert(i)
+ }
+ }
+ }
+
+ return good.count == 3
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -268,6 +289,28 @@ class Solution {
}
```
+```swift
+class Solution {
+ func mergeTriplets(_ triplets: [[Int]], _ target: [Int]) -> Bool {
+ var x = false, y = false, z = false
+
+ for t in triplets {
+ if t[0] <= target[0] && t[1] <= target[1] && t[2] <= target[2] {
+ if t[0] == target[0] { x = true }
+ if t[1] == target[1] { y = true }
+ if t[2] == target[2] { z = true }
+ }
+
+ if x && y && z {
+ return true
+ }
+ }
+
+ return false
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/merge-two-sorted-linked-lists.md b/articles/merge-two-sorted-linked-lists.md
index bffc3e16f..b65407ade 100644
--- a/articles/merge-two-sorted-linked-lists.md
+++ b/articles/merge-two-sorted-linked-lists.md
@@ -203,6 +203,36 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func mergeTwoLists(_ list1: ListNode?, _ list2: ListNode?) -> ListNode? {
+ if list1 == nil {
+ return list2
+ }
+ if list2 == nil {
+ return list1
+ }
+ if list1!.val <= list2!.val {
+ list1!.next = mergeTwoLists(list1!.next, list2)
+ return list1
+ } else {
+ list2!.next = mergeTwoLists(list1, list2!.next)
+ return list2
+ }
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -473,6 +503,42 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func mergeTwoLists(_ list1: ListNode?, _ list2: ListNode?) -> ListNode? {
+ let dummy = ListNode(0)
+ var node = dummy
+ var l1 = list1
+ var l2 = list2
+
+ while l1 != nil && l2 != nil {
+ if l1!.val < l2!.val {
+ node.next = l1
+ l1 = l1?.next
+ } else {
+ node.next = l2
+ l2 = l2?.next
+ }
+ node = node.next!
+ }
+
+ node.next = l1 ?? l2
+
+ return dummy.next
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/min-cost-climbing-stairs.md b/articles/min-cost-climbing-stairs.md
index 3c7139726..9433d007b 100644
--- a/articles/min-cost-climbing-stairs.md
+++ b/articles/min-cost-climbing-stairs.md
@@ -118,6 +118,21 @@ class Solution {
}
```
+```swift
+class Solution {
+ func minCostClimbingStairs(_ cost: [Int]) -> Int {
+ func dfs(_ i: Int) -> Int {
+ if i >= cost.count {
+ return 0
+ }
+ return cost[i] + min(dfs(i + 1), dfs(i + 2))
+ }
+
+ return min(dfs(0), dfs(1))
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -291,6 +306,27 @@ class Solution {
}
```
+```swift
+class Solution {
+ func minCostClimbingStairs(_ cost: [Int]) -> Int {
+ var memo = Array(repeating: -1, count: cost.count)
+
+ func dfs(_ i: Int) -> Int {
+ if i >= cost.count {
+ return 0
+ }
+ if memo[i] != -1 {
+ return memo[i]
+ }
+ memo[i] = cost[i] + min(dfs(i + 1), dfs(i + 2))
+ return memo[i]
+ }
+
+ return min(dfs(0), dfs(1))
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -423,6 +459,22 @@ class Solution {
}
```
+```swift
+class Solution {
+ func minCostClimbingStairs(_ cost: [Int]) -> Int {
+ let n = cost.count
+ var dp = Array(repeating: 0, count: n + 1)
+
+ for i in 2...n {
+ dp[i] = min(dp[i - 1] + cost[i - 1],
+ dp[i - 2] + cost[i - 2])
+ }
+
+ return dp[n]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -523,6 +575,17 @@ class Solution {
}
```
+```swift
+class Solution {
+ func minCostClimbingStairs(_ cost: inout [Int]) -> Int {
+ for i in stride(from: cost.count - 3, through: 0, by: -1) {
+ cost[i] += min(cost[i + 1], cost[i + 2])
+ }
+ return min(cost[0], cost[1])
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/min-cost-to-connect-points.md b/articles/min-cost-to-connect-points.md
index 8e9e5226a..6688ee3a1 100644
--- a/articles/min-cost-to-connect-points.md
+++ b/articles/min-cost-to-connect-points.md
@@ -45,7 +45,7 @@ class Solution:
```
```java
-public class DSU {
+class DSU {
int[] Parent, Size;
public DSU(int n) {
@@ -398,6 +398,68 @@ class Solution {
}
```
+```swift
+class DSU {
+ private var parent: [Int]
+ private var size: [Int]
+
+ init(_ n: Int) {
+ parent = Array(0...n)
+ size = Array(repeating: 1, count: n + 1)
+ }
+
+ func find(_ node: Int) -> Int {
+ if parent[node] != node {
+ parent[node] = find(parent[node])
+ }
+ return parent[node]
+ }
+
+ func union(_ u: Int, _ v: Int) -> Bool {
+ let pu = find(u)
+ let pv = find(v)
+ if pu == pv {
+ return false
+ }
+ if size[pu] < size[pv] {
+ parent[pu] = pv
+ size[pv] += size[pu]
+ } else {
+ parent[pv] = pu
+ size[pu] += size[pv]
+ }
+ return true
+ }
+}
+
+class Solution {
+ func minCostConnectPoints(_ points: [[Int]]) -> Int {
+ let n = points.count
+ let dsu = DSU(n)
+ var edges = [(Int, Int, Int)]()
+
+ for i in 0.. Bool {
+ return lhs.cost < rhs.cost
+ }
+}
+
+class Solution {
+ func minCostConnectPoints(_ points: [[Int]]) -> Int {
+ let N = points.count
+ var adj = [Int: [(Int, Int)]]()
+
+ for i in 0..()
+ var minHeap = Heap
- ()
+ minHeap.insert(Item(cost: 0, node: 0))
+
+ while visit.count < N {
+ guard let item = minHeap.popMin() else { break }
+ let cost = item.cost
+ let i = item.node
+
+ if visit.contains(i) {
+ continue
+ }
+
+ res += cost
+ visit.insert(i)
+
+ if let neighbors = adj[i] {
+ for (neiCost, nei) in neighbors {
+ if !visit.contains(nei) {
+ minHeap.insert(Item(cost: neiCost, node: nei))
+ }
+ }
+ }
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -940,6 +1058,42 @@ class Solution {
}
```
+```swift
+class Solution {
+ func minCostConnectPoints(_ points: [[Int]]) -> Int {
+ let n = points.count
+ var node = 0
+ var dist = Array(repeating: 100000000, count: n)
+ var visit = Array(repeating: false, count: n)
+ var edges = 0
+ var res = 0
+
+ while edges < n - 1 {
+ visit[node] = true
+ var nextNode = -1
+
+ for i in 0.. [Int] {
+ var res = [Int]()
+
+ for q in queries {
+ var cur = -1
+ for interval in intervals {
+ let l = interval[0]
+ let r = interval[1]
+
+ if l <= q && q <= r {
+ if cur == -1 || (r - l + 1) < cur {
+ cur = r - l + 1
+ }
+ }
+ }
+ res.append(cur)
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(m * n)$
-* Space complexity: $O(1)$
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(m)$ space for the output array.
> Where $m$ is the length of the array $queries$ and $n$ is the length of the array $intervals$.
@@ -508,6 +535,78 @@ class Solution {
}
```
+```swift
+struct Event {
+ let time: Int
+ let type: Int // 0: interval start, 1: query, 2: interval end
+ let size: Int? // interval size for start/end events
+ let idx: Int? // index for interval (for start/end) or query index (for query)
+}
+
+struct Item: Comparable {
+ let size: Int
+ let idx: Int
+
+ static func < (lhs: Item, rhs: Item) -> Bool {
+ return lhs.size < rhs.size
+ }
+}
+
+class Solution {
+ func minInterval(_ intervals: [[Int]], _ queries: [Int]) -> [Int] {
+ var events = [Event]()
+
+ // Create events for intervals
+ for (idx, interval) in intervals.enumerated() {
+ let start = interval[0]
+ let end = interval[1]
+ let intervalSize = end - start + 1
+ events.append(Event(time: start, type: 0, size: intervalSize, idx: idx))
+ events.append(Event(time: end, type: 2, size: intervalSize, idx: idx))
+ }
+
+ // Create events for queries
+ for (i, q) in queries.enumerated() {
+ events.append(Event(time: q, type: 1, size: nil, idx: i))
+ }
+
+ // Sort by time and type (end before query)
+ events.sort { (a, b) in
+ if a.time != b.time {
+ return a.time < b.time
+ }
+ return a.type < b.type
+ }
+
+ // Min heap storing [size, index]
+ var sizes = Heap
- ()
+ var ans = Array(repeating: -1, count: queries.count)
+ var inactive = Array(repeating: false, count: intervals.count)
+
+ for event in events {
+ if event.type == 0 { // Interval start
+ let intervalSize = event.size!
+ let idx = event.idx!
+ sizes.insert(Item(size: intervalSize, idx: idx))
+ } else if event.type == 2 { // Interval end
+ let idx = event.idx!
+ inactive[idx] = true
+ } else { // Query
+ let queryIdx = event.idx!
+ while !sizes.isEmpty, inactive[sizes.min!.idx] {
+ sizes.removeMin()
+ }
+ if !sizes.isEmpty {
+ ans[queryIdx] = sizes.min!.size
+ }
+ }
+ }
+
+ return ans
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -779,6 +878,44 @@ class Solution {
}
```
+```swift
+struct HeapItem: Comparable {
+ let size: Int
+ let end: Int
+ static func < (lhs: HeapItem, rhs: HeapItem) -> Bool {
+ if lhs.size == rhs.size {
+ return lhs.end < rhs.end
+ }
+ return lhs.size < rhs.size
+ }
+}
+
+class Solution {
+ func minInterval(_ intervals: [[Int]], _ queries: [Int]) -> [Int] {
+ let sortedIntervals = intervals.sorted { $0[0] < $1[0] }
+ var minHeap = Heap()
+ var res = [Int: Int]()
+ var i = 0
+
+ for q in queries.sorted() {
+ while i < sortedIntervals.count && sortedIntervals[i][0] <= q {
+ let l = sortedIntervals[i][0]
+ let r = sortedIntervals[i][1]
+ minHeap.insert(HeapItem(size: r - l + 1, end: r))
+ i += 1
+ }
+
+ while !minHeap.isEmpty, minHeap.min!.end < q {
+ minHeap.removeMin()
+ }
+ res[q] = minHeap.isEmpty ? -1 : minHeap.min!.size
+ }
+
+ return queries.map { res[$0] ?? -1 }
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -871,7 +1008,7 @@ class Solution:
```
```java
-public class SegmentTree {
+class SegmentTree {
int n;
int[] tree;
int[] lazy;
@@ -1471,11 +1608,120 @@ class Solution {
}
```
+```swift
+class SegmentTree {
+ let n: Int
+ var tree: [Int]
+ var lazy: [Int]
+ let INF = Int.max
+
+ init(_ N: Int) {
+ self.n = N
+ self.tree = [Int](repeating: INF, count: 4 * N)
+ self.lazy = [Int](repeating: INF, count: 4 * N)
+ }
+
+ // Propagate lazy value at tree index over range [lo, hi]
+ func propagate(_ treeidx: Int, _ lo: Int, _ hi: Int) {
+ if lazy[treeidx] != INF {
+ tree[treeidx] = min(tree[treeidx], lazy[treeidx])
+ if lo != hi {
+ lazy[2 * treeidx + 1] = min(lazy[2 * treeidx + 1], lazy[treeidx])
+ lazy[2 * treeidx + 2] = min(lazy[2 * treeidx + 2], lazy[treeidx])
+ }
+ lazy[treeidx] = INF
+ }
+ }
+
+ // Update the segment tree over range [left, right] with value val
+ func update(_ treeidx: Int, _ lo: Int, _ hi: Int, _ left: Int, _ right: Int, _ val: Int) {
+ propagate(treeidx, lo, hi)
+ if lo > right || hi < left {
+ return
+ }
+ if lo >= left && hi <= right {
+ lazy[treeidx] = min(lazy[treeidx], val)
+ propagate(treeidx, lo, hi)
+ return
+ }
+ let mid = (lo + hi) / 2
+ update(2 * treeidx + 1, lo, mid, left, right, val)
+ update(2 * treeidx + 2, mid + 1, hi, left, right, val)
+ tree[treeidx] = min(tree[2 * treeidx + 1], tree[2 * treeidx + 2])
+ }
+
+ // Query the value at index idx in the original array
+ func query(_ treeidx: Int, _ lo: Int, _ hi: Int, _ idx: Int) -> Int {
+ propagate(treeidx, lo, hi)
+ if lo == hi {
+ return tree[treeidx]
+ }
+ let mid = (lo + hi) / 2
+ if idx <= mid {
+ return query(2 * treeidx + 1, lo, mid, idx)
+ } else {
+ return query(2 * treeidx + 2, mid + 1, hi, idx)
+ }
+ }
+
+ func update_range(_ left: Int, _ right: Int, _ val: Int) {
+ update(0, 0, n - 1, left, right, val)
+ }
+
+ func query_point(_ idx: Int) -> Int {
+ return query(0, 0, n - 1, idx)
+ }
+}
+
+class Solution {
+ func minInterval(_ intervals: [[Int]], _ queries: [Int]) -> [Int] {
+ var points = [Int]()
+ // Create events for intervals
+ for interval in intervals {
+ points.append(interval[0])
+ points.append(interval[1])
+ }
+ // Create events for queries
+ for q in queries {
+ points.append(q)
+ }
+
+ // Compress the coordinates
+ let sortedPoints = Array(Set(points)).sorted()
+ var compress = [Int: Int]()
+ for (i, point) in sortedPoints.enumerated() {
+ compress[point] = i
+ }
+
+ // Lazy Segment Tree
+ let segTree = SegmentTree(sortedPoints.count)
+
+ for interval in intervals {
+ let start = compress[interval[0]]!
+ let end = compress[interval[1]]!
+ let length = interval[1] - interval[0] + 1
+ segTree.update_range(start, end, length)
+ }
+
+ var ans = [Int]()
+ for q in queries {
+ let idx = compress[q]!
+ // Query for minSize
+ let res = segTree.query_point(idx)
+ ans.append(res == segTree.INF ? -1 : res)
+ }
+ return ans
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O((n + m)\log k)$
-* Space complexity: $O(k)$
+* Space complexity:
+ * $O(k)$ extra space.
+ * $O(m)$ space for the output array.
> Where $m$ is the length of the array $queries$, $n$ is the length of the array $intervals$ and $k$ is the number of unique points.
\ No newline at end of file
diff --git a/articles/minimum-stack.md b/articles/minimum-stack.md
index 28527e995..29041a02c 100644
--- a/articles/minimum-stack.md
+++ b/articles/minimum-stack.md
@@ -278,6 +278,42 @@ class MinStack() {
}
```
+```swift
+class MinStack {
+ private var stack: [Int] = []
+
+ init() {}
+
+ func push(_ val: Int) {
+ stack.append(val)
+ }
+
+ func pop() {
+ stack.popLast()
+ }
+
+ func top() -> Int {
+ return stack.last!
+ }
+
+ func getMin() -> Int {
+ var tmp = [Int]()
+ var mini = stack.last!
+
+ while !stack.isEmpty {
+ mini = min(mini, stack.last!)
+ tmp.append(stack.removeLast())
+ }
+
+ while !tmp.isEmpty {
+ stack.append(tmp.removeLast())
+ }
+
+ return mini
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -524,6 +560,34 @@ class MinStack() {
}
```
+```swift
+class MinStack {
+ private var stack: [Int] = []
+ private var minStack: [Int] = []
+
+ init() {}
+
+ func push(_ val: Int) {
+ stack.append(val)
+ let minVal = min(val, minStack.last ?? val)
+ minStack.append(minVal)
+ }
+
+ func pop() {
+ stack.popLast()
+ minStack.popLast()
+ }
+
+ func top() -> Int {
+ return stack.last!
+ }
+
+ func getMin() -> Int {
+ return minStack.last!
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -543,14 +607,14 @@ class MinStack:
self.min = float('inf')
self.stack = []
- def push(self, x: int) -> None:
+ def push(self, val: int) -> None:
if not self.stack:
self.stack.append(0)
- self.min = x
+ self.min = val
else:
- self.stack.append(x - self.min)
- if x < self.min:
- self.min = x
+ self.stack.append(val - self.min)
+ if val < self.min:
+ self.min = val
def pop(self) -> None:
if not self.stack:
@@ -581,13 +645,13 @@ public class MinStack {
stack = new Stack<>();
}
- public void push(int x) {
+ public void push(int val) {
if (stack.isEmpty()) {
stack.push(0L);
- min = x;
+ min = val;
} else {
- stack.push(x - min);
- if (x < min) min = x;
+ stack.push(val - min);
+ if (val < min) min = val;
}
}
@@ -621,9 +685,7 @@ private:
std::stack stack;
public:
- MinStack() {
-
- }
+ MinStack() {}
void push(int val) {
if (stack.empty()) {
@@ -755,14 +817,14 @@ func Constructor() MinStack {
}
}
-func (this *MinStack) Push(x int) {
+func (this *MinStack) Push(val int) {
if len(this.stack) == 0 {
this.stack = append(this.stack, 0)
- this.min = x
+ this.min = val
} else {
- this.stack = append(this.stack, x - this.min)
- if x < this.min {
- this.min = x
+ this.stack = append(this.stack, val - this.min)
+ if val < this.min {
+ this.min = val
}
}
}
@@ -796,8 +858,8 @@ class MinStack() {
private var min: Long = Long.MAX_VALUE
private val stack = ArrayDeque()
- fun push(x: Int) {
- val valAsLong = x.toLong()
+ fun push(`val`: Int) {
+ val valAsLong = `val`.toLong()
if (stack.isEmpty()) {
stack.addLast(0L)
min = valAsLong
@@ -828,6 +890,48 @@ class MinStack() {
}
```
+```swift
+class MinStack {
+ private var minVal: Int = Int.max
+ private var stack: [Int] = []
+
+ init() {}
+
+ func push(_ val: Int) {
+ if stack.isEmpty {
+ stack.append(0)
+ minVal = val
+ } else {
+ stack.append(val - minVal)
+ if val < minVal {
+ minVal = val
+ }
+ }
+ }
+
+ func pop() {
+ if stack.isEmpty {
+ return
+ }
+
+ let pop = stack.removeLast()
+
+ if pop < 0 {
+ minVal -= pop
+ }
+ }
+
+ func top() -> Int {
+ let top = stack.last!
+ return top > 0 ? top + minVal : minVal
+ }
+
+ func getMin() -> Int {
+ return minVal
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/minimum-window-with-characters.md b/articles/minimum-window-with-characters.md
index 9e0b36005..887cb769c 100644
--- a/articles/minimum-window-with-characters.md
+++ b/articles/minimum-window-with-characters.md
@@ -279,6 +279,48 @@ class Solution {
}
```
+```swift
+class Solution {
+ func minWindow(_ s: String, _ t: String) -> String {
+ if t.isEmpty {
+ return ""
+ }
+
+ var countT = [Character: Int]()
+ for c in t {
+ countT[c, default: 0] += 1
+ }
+
+ var res = [-1, -1]
+ var resLen = Int.max
+ let chars = Array(s)
+
+ for i in 0.. countS[c, default: 0] {
+ flag = false
+ break
+ }
+ }
+
+ if flag && (j - i + 1) < resLen {
+ resLen = j - i + 1
+ res = [i, j]
+ }
+ }
+ }
+
+ let (l, r) = (res[0], res[1])
+ return resLen != Int.max ? String(chars[l...r]) : ""
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -608,6 +650,53 @@ class Solution {
}
```
+```swift
+class Solution {
+ func minWindow(_ s: String, _ t: String) -> String {
+ if t.isEmpty {
+ return ""
+ }
+
+ var countT = [Character: Int]()
+ var window = [Character: Int]()
+ for c in t {
+ countT[c, default: 0] += 1
+ }
+
+ var have = 0, need = countT.count
+ var res = [-1, -1], resLen = Int.max
+ let chars = Array(s)
+ var l = 0
+
+ for r in 0.. Int {
+ var nums = nums.sorted()
+ let n = nums.count
+ for i in 0.. Int {
+ let numSet = Set(nums)
+ let n = nums.count
+ for i in 0...n {
+ if !numSet.contains(i) {
+ return i
+ }
+ }
+ return -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -331,6 +361,21 @@ class Solution {
}
```
+```swift
+class Solution {
+ func missingNumber(_ nums: [Int]) -> Int {
+ let n = nums.count
+ var xorr = n
+
+ for i in 0.. Int {
+ var res = nums.count
+
+ for i in 0.. String {
+ if num1 == "0" || num2 == "0" {
+ return "0"
+ }
+ if num1.count < num2.count {
+ return multiply(num2, num1)
+ }
+
+ var res = ""
+ var zero = 0
+ let num2Arr = Array(num2)
+
+ for i in stride(from: num2Arr.count - 1, through: 0, by: -1) {
+ let cur = mul(num1, num2Arr[i], zero)
+ res = add(res, cur)
+ zero += 1
+ }
+
+ return res
+ }
+
+ func mul(_ s: String, _ d: Character, _ zero: Int) -> String {
+ var i = s.count - 1
+ var carry = 0
+ let dInt = Int(String(d))!
+ let sArr = Array(s)
+ var cur = [String]()
+
+ while i >= 0 || carry > 0 {
+ let n = i >= 0 ? Int(String(sArr[i]))! : 0
+ let prod = n * dInt + carry
+ cur.append(String(prod % 10))
+ carry = prod / 10
+ i -= 1
+ }
+
+ let prodStr = cur.reversed().joined()
+ let zeros = String(repeating: "0", count: zero)
+ return prodStr + zeros
+ }
+
+ func add(_ num1: String, _ num2: String) -> String {
+ let s1 = Array(num1)
+ let s2 = Array(num2)
+ var i = s1.count - 1
+ var j = s2.count - 1
+ var carry = 0
+ var res = [String]()
+
+ while i >= 0 || j >= 0 || carry > 0 {
+ let n1 = i >= 0 ? Int(String(s1[i]))! : 0
+ let n2 = j >= 0 ? Int(String(s2[j]))! : 0
+ let total = n1 + n2 + carry
+ res.append(String(total % 10))
+ carry = total / 10
+ i -= 1
+ j -= 1
+ }
+
+ return res.reversed().joined()
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -667,6 +733,37 @@ class Solution {
}
```
+```swift
+class Solution {
+ func multiply(_ num1: String, _ num2: String) -> String {
+ if num1 == "0" || num2 == "0" {
+ return "0"
+ }
+
+ let n1 = Array(num1.reversed()).map { Int(String($0))! }
+ let n2 = Array(num2.reversed()).map { Int(String($0))! }
+ var res = [Int](repeating: 0, count: num1.count + num2.count)
+
+ for i1 in 0.. [[String]] {
+ var res = [[String]]()
+ var board = Array(repeating: Array(repeating: ".", count: n), count: n)
+
+ func backtrack(_ r: Int) {
+ if r == n {
+ let copy = board.map { $0.joined() }
+ res.append(copy)
+ return
+ }
+ for c in 0.. Bool {
+ var row = r - 1
+ while row >= 0 {
+ if board[row][c] == "Q" { return false }
+ row -= 1
+ }
+
+ var row1 = r - 1, col1 = c - 1
+ while row1 >= 0, col1 >= 0 {
+ if board[row1][col1] == "Q" { return false }
+ row1 -= 1
+ col1 -= 1
+ }
+
+ var row2 = r - 1, col2 = c + 1
+ while row2 >= 0, col2 < board.count {
+ if board[row2][col2] == "Q" { return false }
+ row2 -= 1
+ col2 += 1
+ }
+
+ return true
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -666,6 +717,47 @@ class Solution {
}
```
+```swift
+class Solution {
+ func solveNQueens(_ n: Int) -> [[String]] {
+ var col = Set()
+ var posDiag = Set()
+ var negDiag = Set()
+ var res = [[String]]()
+ var board = Array(repeating: Array(repeating: ".", count: n), count: n)
+
+ func backtrack(_ r: Int) {
+ if r == n {
+ let copy = board.map { $0.joined() }
+ res.append(copy)
+ return
+ }
+
+ for c in 0.. [[String]] {
+ var col = Array(repeating: false, count: n)
+ var posDiag = Array(repeating: false, count: 2 * n)
+ var negDiag = Array(repeating: false, count: 2 * n)
+ var res = [[String]]()
+ var board = Array(repeating: Array(repeating: ".", count: n), count: n)
+
+ func backtrack(_ r: Int) {
+ if r == n {
+ let copy = board.map { $0.joined() }
+ res.append(copy)
+ return
+ }
+
+ for c in 0.. [[String]] {
+ var col = 0
+ var posDiag = 0
+ var negDiag = 0
+ var res = [[String]]()
+ var board = Array(repeating: Array(repeating: ".", count: n), count: n)
+
+ func backtrack(_ r: Int) {
+ if r == n {
+ let copy = board.map { $0.joined() }
+ res.append(copy)
+ return
+ }
+
+ for c in 0.. Int {
+ var adj = [Int: [(Int, Int)]]()
+ for time in times {
+ let u = time[0], v = time[1], w = time[2]
+ adj[u, default: []].append((v, w))
+ }
+
+ var dist = [Int: Int]()
+ for node in 1...n {
+ dist[node] = Int.max
+ }
+
+ func dfs(_ node: Int, _ time: Int) {
+ if time >= dist[node]! {
+ return
+ }
+
+ dist[node] = time
+ if let neighbors = adj[node] {
+ for (nei, w) in neighbors {
+ dfs(nei, time + w)
+ }
+ }
+ }
+
+ dfs(k, 0)
+ let res = dist.values.max()!
+ return res == Int.max ? -1 : res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -450,6 +484,34 @@ class Solution {
}
```
+```swift
+class Solution {
+ func networkDelayTime(_ times: [[Int]], _ n: Int, _ k: Int) -> Int {
+ let inf = Int.max / 2
+ var dist = Array(repeating: Array(repeating: inf, count: n), count: n)
+
+ for time in times {
+ let u = time[0] - 1, v = time[1] - 1, w = time[2]
+ dist[u][v] = w
+ }
+ for i in 0..= inf ? -1 : res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -621,6 +683,32 @@ class Solution {
}
```
+```swift
+class Solution {
+ func networkDelayTime(_ times: [[Int]], _ n: Int, _ k: Int) -> Int {
+ var dist = Array(repeating: Int.max, count: n)
+ dist[k - 1] = 0
+
+ for _ in 0.. Int {
+ var adj = [Int: [(Int, Int)]]()
+ for time in times {
+ let u = time[0], v = time[1], w = time[2]
+ adj[u, default: []].append((v, w))
+ }
+
+ var dist = [Int: Int]()
+ for node in 1...n {
+ dist[node] = Int.max
+ }
+ dist[k] = 0
+
+ var queue = Deque<(Int, Int)>()
+ queue.append((k, 0))
+
+ while !queue.isEmpty {
+ let (node, time) = queue.popFirst()!
+ if dist[node]! < time {
+ continue
+ }
+ if let neighbors = adj[node] {
+ for (nei, w) in neighbors {
+ if time + w < dist[nei]! {
+ dist[nei] = time + w
+ queue.append((nei, time + w))
+ }
+ }
+ }
+ }
+
+ let res = dist.values.max()!
+ return res == Int.max ? -1 : res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1175,6 +1302,53 @@ class Solution {
}
```
+```swift
+struct Item: Comparable {
+ let weight: Int
+ let node: Int
+
+ static func < (lhs: Item, rhs: Item) -> Bool {
+ return lhs.weight < rhs.weight
+ }
+}
+
+class Solution {
+ func networkDelayTime(_ times: [[Int]], _ n: Int, _ k: Int) -> Int {
+ var edges = [Int: [(Int, Int)]]()
+ for time in times {
+ let u = time[0], v = time[1], w = time[2]
+ edges[u, default: []].append((v, w))
+ }
+
+ var minHeap = Heap
- ()
+ minHeap.insert(Item(weight: 0, node: k))
+ var visit = Set()
+ var t = 0
+
+ while !minHeap.isEmpty {
+ let item = minHeap.removeMin()
+ let w1 = item.weight
+ let n1 = item.node
+
+ if visit.contains(n1) {
+ continue
+ }
+ visit.insert(n1)
+ t = w1
+
+ if let neighbors = edges[n1] {
+ for (n2, w2) in neighbors {
+ if !visit.contains(n2) {
+ minHeap.insert(Item(weight: w1 + w2, node: n2))
+ }
+ }
+ }
+ }
+ return visit.count == n ? t : -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/non-cyclical-number.md b/articles/non-cyclical-number.md
index 5290a69a7..6b3053011 100644
--- a/articles/non-cyclical-number.md
+++ b/articles/non-cyclical-number.md
@@ -206,6 +206,36 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isHappy(_ n: Int) -> Bool {
+ var visit = Set()
+ var num = n
+
+ while !visit.contains(num) {
+ visit.insert(num)
+ num = sumOfSquares(num)
+ if num == 1 {
+ return true
+ }
+ }
+ return false
+ }
+
+ private func sumOfSquares(_ n: Int) -> Int {
+ var num = n
+ var output = 0
+
+ while num > 0 {
+ let digit = num % 10
+ output += digit * digit
+ num /= 10
+ }
+ return output
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -404,6 +434,34 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isHappy(_ n: Int) -> Bool {
+ var slow = n
+ var fast = sumOfSquares(n)
+
+ while slow != fast {
+ fast = sumOfSquares(fast)
+ fast = sumOfSquares(fast)
+ slow = sumOfSquares(slow)
+ }
+ return fast == 1
+ }
+
+ private func sumOfSquares(_ n: Int) -> Int {
+ var num = n
+ var output = 0
+
+ while num > 0 {
+ let digit = num % 10
+ output += digit * digit
+ num /= 10
+ }
+ return output
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -636,6 +694,40 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isHappy(_ n: Int) -> Bool {
+ var slow = n
+ var fast = sumOfSquares(n)
+ var power = 1
+ var lam = 1
+
+ while slow != fast {
+ if power == lam {
+ slow = fast
+ power *= 2
+ lam = 0
+ }
+ fast = sumOfSquares(fast)
+ lam += 1
+ }
+ return fast == 1
+ }
+
+ private func sumOfSquares(_ n: Int) -> Int {
+ var num = n
+ var output = 0
+
+ while num > 0 {
+ let digit = num % 10
+ output += digit * digit
+ num /= 10
+ }
+ return output
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/non-overlapping-intervals.md b/articles/non-overlapping-intervals.md
index 7970155cb..60f0b89a1 100644
--- a/articles/non-overlapping-intervals.md
+++ b/articles/non-overlapping-intervals.md
@@ -147,6 +147,28 @@ class Solution {
}
```
+```swift
+class Solution {
+ func eraseOverlapIntervals(_ intervals: [[Int]]) -> Int {
+ var intervals = intervals
+ intervals.sort { $0[0] < $1[0] }
+
+ func dfs(_ i: Int, _ prev: Int) -> Int {
+ if i == intervals.count {
+ return 0
+ }
+ var res = dfs(i + 1, prev)
+ if prev == -1 || intervals[prev][1] <= intervals[i][0] {
+ res = max(res, 1 + dfs(i + 1, i))
+ }
+ return res
+ }
+
+ return intervals.count - dfs(0, -1)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -365,6 +387,34 @@ class Solution {
}
```
+```swift
+class Solution {
+ func eraseOverlapIntervals(_ intervals: [[Int]]) -> Int {
+ var intervals = intervals
+ intervals.sort { $0[1] < $1[1] }
+ let n = intervals.count
+ var memo = [Int: Int]()
+
+ func dfs(_ i: Int) -> Int {
+ if let result = memo[i] {
+ return result
+ }
+
+ var res = 1
+ for j in i + 1.. Int {
+ var intervals = intervals
+ intervals.sort { $0[1] < $1[1] }
+ let n = intervals.count
+ var dp = [Int](repeating: 0, count: n)
+
+ for i in 0.. Int {
+ var intervals = intervals
+ intervals.sort { $0[1] < $1[1] }
+ let n = intervals.count
+ var dp = [Int](repeating: 0, count: n)
+ dp[0] = 1
+
+ func bs(_ r: Int, _ target: Int) -> Int {
+ var l = 0
+ var r = r
+ while l < r {
+ let m = (l + r) >> 1
+ if intervals[m][1] <= target {
+ l = m + 1
+ } else {
+ r = m
+ }
+ }
+ return l
+ }
+
+ for i in 1.. Int {
+ var intervals = intervals
+ intervals.sort { $0[0] < $1[0] }
+
+ var res = 0
+ var prevEnd = intervals[0][1]
+
+ for i in 1..= prevEnd {
+ prevEnd = end
+ } else {
+ res += 1
+ prevEnd = min(end, prevEnd)
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1142,6 +1275,28 @@ class Solution {
}
```
+```swift
+class Solution {
+ func eraseOverlapIntervals(_ intervals: [[Int]]) -> Int {
+ var intervals = intervals
+ intervals.sort { $0[1] < $1[1] }
+
+ var prevEnd = intervals[0][1]
+ var res = 0
+
+ for i in 1.. intervals[i][0] {
+ res += 1
+ } else {
+ prevEnd = intervals[i][1]
+ }
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/number-of-one-bits.md b/articles/number-of-one-bits.md
index 9468bf89b..4ea545b0d 100644
--- a/articles/number-of-one-bits.md
+++ b/articles/number-of-one-bits.md
@@ -99,6 +99,20 @@ class Solution {
}
```
+```swift
+class Solution {
+ func hammingWeight(_ n: Int) -> Int {
+ var res = 0
+ for i in 0..<32 {
+ if (1 << i) & n != 0 {
+ res += 1
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -208,6 +222,20 @@ class Solution {
}
```
+```swift
+class Solution {
+ func hammingWeight(_ n: Int) -> Int {
+ var n = n
+ var res = 0
+ while n != 0 {
+ res += (n & 1) != 0 ? 1 : 0
+ n >>= 1
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -313,6 +341,20 @@ class Solution {
}
```
+```swift
+class Solution {
+ func hammingWeight(_ n: Int) -> Int {
+ var n = n
+ var res = 0
+ while n != 0 {
+ n &= (n - 1)
+ res += 1
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -383,6 +425,14 @@ class Solution {
}
```
+```swift
+class Solution {
+ func hammingWeight(_ n: Int) -> Int {
+ return n.nonzeroBitCount
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/pacific-atlantic-water-flow.md b/articles/pacific-atlantic-water-flow.md
index 1b718571a..1245a570d 100644
--- a/articles/pacific-atlantic-water-flow.md
+++ b/articles/pacific-atlantic-water-flow.md
@@ -351,6 +351,57 @@ class Solution {
}
```
+```swift
+class Solution {
+ func pacificAtlantic(_ heights: [[Int]]) -> [[Int]] {
+ var heights = heights
+ let ROWS = heights.count
+ let COLS = heights[0].count
+ let directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
+
+ var pacific = false
+ var atlantic = false
+
+ func dfs(_ r: Int, _ c: Int, _ prevVal: Int) {
+ if r < 0 || c < 0 {
+ pacific = true
+ return
+ }
+ if r >= ROWS || c >= COLS {
+ atlantic = true
+ return
+ }
+ if heights[r][c] > prevVal {
+ return
+ }
+
+ let tmp = heights[r][c]
+ heights[r][c] = Int.max
+ for dir in directions {
+ dfs(r + dir.0, c + dir.1, tmp)
+ if pacific && atlantic {
+ break
+ }
+ }
+ heights[r][c] = tmp
+ }
+
+ var res = [[Int]]()
+ for r in 0.. [[Int]] {
+ let ROWS = heights.count
+ let COLS = heights[0].count
+ var pac = Set<[Int]>()
+ var atl = Set<[Int]>()
+
+ func dfs(_ r: Int, _ c: Int, _ visit: inout Set<[Int]>, _ prevHeight: Int) {
+ if (visit.contains([r, c]) || r < 0 || c < 0 || r == ROWS ||
+ c == COLS || heights[r][c] < prevHeight) {
+ return
+ }
+ visit.insert([r, c])
+ dfs(r + 1, c, &visit, heights[r][c])
+ dfs(r - 1, c, &visit, heights[r][c])
+ dfs(r, c + 1, &visit, heights[r][c])
+ dfs(r, c - 1, &visit, heights[r][c])
+ }
+
+ for c in 0.. [[Int]] {
+ let ROWS = heights.count
+ let COLS = heights[0].count
+ let directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
+
+ var pac = Array(repeating: Array(repeating: false, count: COLS), count: ROWS)
+ var atl = Array(repeating: Array(repeating: false, count: COLS), count: ROWS)
+
+ func bfs(_ source: [(Int, Int)], _ ocean: inout [[Bool]]) {
+ var queue = Deque(source)
+ while !queue.isEmpty {
+ let (r, c) = queue.popFirst()!
+ ocean[r][c] = true
+ for dir in directions {
+ let nr = r + dir.0
+ let nc = c + dir.1
+ if nr >= 0, nr < ROWS, nc >= 0, nc < COLS,
+ !ocean[nr][nc], heights[nr][nc] >= heights[r][c] {
+ queue.append((nr, nc))
+ }
+ }
+ }
+ }
+
+ var pacific: [(Int, Int)] = []
+ var atlantic: [(Int, Int)] = []
+
+ for c in 0.. [[String]] {
+ var res = [[String]]()
+ var part = [String]()
+ let sArray = Array(s)
+
+ func dfs(_ j: Int, _ i: Int) {
+ if i >= sArray.count {
+ if i == j {
+ res.append(part)
+ }
+ return
+ }
+
+ if isPali(sArray, j, i) {
+ part.append(String(sArray[j...i]))
+ dfs(i + 1, i + 1)
+ part.removeLast()
+ }
+
+ dfs(j, i + 1)
+ }
+
+ func isPali(_ s: [Character], _ l: Int, _ r: Int) -> Bool {
+ var l = l, r = r
+ while l < r {
+ if s[l] != s[r] {
+ return false
+ }
+ l += 1
+ r -= 1
+ }
+ return true
+ }
+
+ dfs(0, 0)
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(n * 2 ^ n)$
-* Space complexity: $O(n)$
+* Space complexity:
+ * $O(n)$ extra space.
+ * $O(n * 2 ^ n)$ space for the output list.
---
-## 2. Backtracking
+## 2. Backtracking - II
::tabs-start
@@ -562,12 +606,53 @@ class Solution {
}
```
+```swift
+class Solution {
+ func partition(_ s: String) -> [[String]] {
+ var res = [[String]]()
+ var part = [String]()
+ let sArray = Array(s)
+
+ func dfs(_ i: Int) {
+ if i >= sArray.count {
+ res.append(part)
+ return
+ }
+ for j in i.. Bool {
+ var l = l, r = r
+ while l < r {
+ if s[l] != s[r] {
+ return false
+ }
+ l += 1
+ r -= 1
+ }
+ return true
+ }
+
+ dfs(0)
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(n * 2 ^ n)$
-* Space complexity: $O(n)$
+* Space complexity:
+ * $O(n)$ extra space.
+ * $O(n * 2 ^ n)$ space for the output list.
---
@@ -823,12 +908,51 @@ class Solution {
}
```
+```swift
+class Solution {
+ func partition(_ s: String) -> [[String]] {
+ let n = s.count
+ let sArray = Array(s)
+ var dp = Array(repeating: Array(repeating: false, count: n), count: n)
+
+ for l in 1...n {
+ for i in 0...(n - l) {
+ dp[i][i + l - 1] = (sArray[i] == sArray[i + l - 1] &&
+ (i + 1 > (i + l - 2) || dp[i + 1][i + l - 2]))
+ }
+ }
+
+ var res = [[String]]()
+ var part = [String]()
+
+ func dfs(_ i: Int) {
+ if i >= sArray.count {
+ res.append(part)
+ return
+ }
+ for j in i.. [[String]] {
+ let n = s.count
+ let sArray = Array(s)
+ var dp = Array(repeating: Array(repeating: false, count: n), count: n)
+
+ for l in 1...n {
+ for i in 0...(n - l) {
+ dp[i][i + l - 1] = (sArray[i] == sArray[i + l - 1] &&
+ (i + 1 > (i + l - 2) || dp[i + 1][i + l - 2]))
+ }
+ }
+
+ func dfs(_ i: Int) -> [[String]] {
+ if i >= n {
+ return [[]]
+ }
+
+ var ret = [[String]]()
+ for j in i.. Int {
+ let chars = Array(s)
+ var res = 0
+
+ for i in 0..= r {
+ res += 1
+ }
+ }
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -313,6 +337,28 @@ class Solution {
}
```
+```swift
+class Solution {
+ func countSubstrings(_ s: String) -> Int {
+ let n = s.count
+ var res = 0
+ var dp = Array(repeating: Array(repeating: false, count: n), count: n)
+ let chars = Array(s)
+
+ for i in stride(from: n - 1, through: 0, by: -1) {
+ for j in i.. Int {
+ let chars = Array(s)
+ var res = 0
+
+ for i in 0..= 0 && r < chars.count && chars[l] == chars[r] {
+ res += 1
+ l -= 1
+ r += 1
+ }
+
+ // Even length palindromes
+ l = i
+ r = i + 1
+ while l >= 0 && r < chars.count && chars[l] == chars[r] {
+ res += 1
+ l -= 1
+ r += 1
+ }
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -722,6 +798,33 @@ class Solution {
}
```
+```swift
+class Solution {
+ func countSubstrings(_ s: String) -> Int {
+ var res = 0
+ let chars = Array(s)
+
+ for i in 0.. Int {
+ var res = 0
+ var left = l, right = r
+
+ while left >= 0 && right < s.count && s[left] == s[right] {
+ res += 1
+ left -= 1
+ right += 1
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -982,6 +1085,42 @@ class Solution {
}
```
+```swift
+class Solution {
+ func countSubstrings(_ s: String) -> Int {
+ func manacher(_ s: String) -> [Int] {
+ let t = "#" + s.map { "\($0)#" }.joined()
+ let chars = Array(t)
+ let n = chars.count
+ var p = Array(repeating: 0, count: n)
+ var l = 0, r = 0
+
+ for i in 0..= 0,
+ chars[i + p[i] + 1] == chars[i - p[i] - 1] {
+ p[i] += 1
+ }
+ if i + p[i] > r {
+ l = i - p[i]
+ r = i + p[i]
+ }
+ }
+ return p
+ }
+
+ let p = manacher(s)
+ var res = 0
+ for i in p {
+ res += (i + 1) / 2
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/partition-equal-subset-sum.md b/articles/partition-equal-subset-sum.md
index d51654692..6d6fd0caa 100644
--- a/articles/partition-equal-subset-sum.md
+++ b/articles/partition-equal-subset-sum.md
@@ -194,6 +194,33 @@ class Solution {
}
```
+```swift
+class Solution {
+ func canPartition(_ nums: [Int]) -> Bool {
+ let totalSum = nums.reduce(0, +)
+ if totalSum % 2 != 0 {
+ return false
+ }
+
+ let target = totalSum / 2
+ let n = nums.count
+
+ func dfs(_ i: Int, _ target: Int) -> Bool {
+ if i >= n {
+ return target == 0
+ }
+ if target < 0 {
+ return false
+ }
+
+ return dfs(i + 1, target) || dfs(i + 1, target - nums[i])
+ }
+
+ return dfs(0, target)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -454,6 +481,39 @@ class Solution {
}
```
+```swift
+class Solution {
+ func canPartition(_ nums: [Int]) -> Bool {
+ let total = nums.reduce(0, +)
+ if total % 2 != 0 {
+ return false
+ }
+
+ let target = total / 2
+ let n = nums.count
+ var memo = Array(repeating: Array(repeating: -1, count: target + 1), count: n + 1)
+
+ func dfs(_ i: Int, _ target: Int) -> Bool {
+ if target == 0 {
+ return true
+ }
+ if i >= n || target < 0 {
+ return false
+ }
+ if memo[i][target] != -1 {
+ return memo[i][target] == 1
+ }
+
+ let result = dfs(i + 1, target) || dfs(i + 1, target - nums[i])
+ memo[i][target] = result ? 1 : 0
+ return result
+ }
+
+ return dfs(0, target)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -702,6 +762,37 @@ class Solution {
}
```
+```swift
+class Solution {
+ func canPartition(_ nums: [Int]) -> Bool {
+ let total = nums.reduce(0, +)
+ if total % 2 != 0 {
+ return false
+ }
+
+ let target = total / 2
+ let n = nums.count
+ var dp = Array(repeating: Array(repeating: false, count: target + 1), count: n + 1)
+
+ for i in 0...n {
+ dp[i][0] = true
+ }
+
+ for i in 1...n {
+ for j in 1...target {
+ if nums[i - 1] <= j {
+ dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]]
+ } else {
+ dp[i][j] = dp[i - 1][j]
+ }
+ }
+ }
+
+ return dp[n][target]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -940,6 +1031,34 @@ class Solution {
}
```
+```swift
+class Solution {
+ func canPartition(_ nums: [Int]) -> Bool {
+ if nums.reduce(0, +) % 2 != 0 {
+ return false
+ }
+
+ let target = nums.reduce(0, +) / 2
+ var dp = Array(repeating: false, count: target + 1)
+ var nextDp = Array(repeating: false, count: target + 1)
+
+ dp[0] = true
+ for num in nums {
+ for j in stride(from: target, through: 1, by: -1) {
+ if j >= num {
+ nextDp[j] = dp[j] || dp[j - num]
+ } else {
+ nextDp[j] = dp[j]
+ }
+ }
+ swap(&dp, &nextDp)
+ }
+
+ return dp[target]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1147,6 +1266,32 @@ class Solution {
}
```
+```swift
+class Solution {
+ func canPartition(_ nums: [Int]) -> Bool {
+ if nums.reduce(0, +) % 2 != 0 {
+ return false
+ }
+
+ var dp: Set = [0]
+ let target = nums.reduce(0, +) / 2
+
+ for i in stride(from: nums.count - 1, through: 0, by: -1) {
+ var nextDP: Set = []
+ for t in dp {
+ if t + nums[i] == target {
+ return true
+ }
+ nextDP.insert(t + nums[i])
+ nextDP.insert(t)
+ }
+ dp = nextDP
+ }
+ return false
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1342,6 +1487,28 @@ class Solution {
}
```
+```swift
+class Solution {
+ func canPartition(_ nums: [Int]) -> Bool {
+ if nums.reduce(0, +) % 2 != 0 {
+ return false
+ }
+
+ let target = nums.reduce(0, +) / 2
+ var dp = Array(repeating: false, count: target + 1)
+
+ dp[0] = true
+ for num in nums {
+ for j in stride(from: target, through: num, by: -1) {
+ dp[j] = dp[j] || dp[j - num]
+ }
+ }
+
+ return dp[target]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1366,10 +1533,10 @@ class Solution:
target = total // 2
dp = 1 << 0
-
+
for num in nums:
dp |= dp << num
-
+
return (dp & (1 << target)) != 0
```
diff --git a/articles/partition-labels.md b/articles/partition-labels.md
index 5eb089e85..1e4e2b3a1 100644
--- a/articles/partition-labels.md
+++ b/articles/partition-labels.md
@@ -169,6 +169,31 @@ class Solution {
}
```
+```swift
+class Solution {
+ func partitionLabels(_ s: String) -> [Int] {
+ var lastIndex = [Character: Int]()
+ for (i, c) in s.enumerated() {
+ lastIndex[c] = i
+ }
+
+ var res = [Int]()
+ var size = 0
+ var end = 0
+ for (i, c) in s.enumerated() {
+ size += 1
+ end = max(end, lastIndex[c]!)
+
+ if i == end {
+ res.append(size)
+ size = 0
+ }
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/permutation-string.md b/articles/permutation-string.md
index 07e79c7ef..482890ee4 100644
--- a/articles/permutation-string.md
+++ b/articles/permutation-string.md
@@ -149,6 +149,25 @@ class Solution {
}
```
+```swift
+class Solution {
+ func checkInclusion(_ s1: String, _ s2: String) -> Bool {
+ let s1Sorted = s1.sorted()
+ let chars = Array(s2)
+
+ for i in 0.. Bool {
+ var count1 = [Character: Int]()
+ for c in s1 {
+ count1[c, default: 0] += 1
+ }
+
+ let need = count1.count
+ let chars = Array(s2)
+
+ for i in 0.. Where $n$ is the length of the string1 and $m$ is the length of string2.
@@ -736,6 +788,61 @@ class Solution {
}
```
+```swift
+class Solution {
+ func checkInclusion(_ s1: String, _ s2: String) -> Bool {
+ if s1.count > s2.count {
+ return false
+ }
+
+ var s1Count = [Int](repeating: 0, count: 26)
+ var s2Count = [Int](repeating: 0, count: 26)
+ let aAscii = Int(Character("a").asciiValue!)
+
+ let s1Array = Array(s1)
+ let s2Array = Array(s2)
+
+ for i in 0.. [[Int]] {
+ if nums.isEmpty {
+ return [[]]
+ }
+
+ let perms = permute(Array(nums.dropFirst()))
+ var res = [[Int]]()
+
+ for p in perms {
+ for i in 0...p.count {
+ var pCopy = p
+ pCopy.insert(nums[0], at: i)
+ res.append(pCopy)
+ }
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -303,6 +326,28 @@ class Solution {
}
```
+```swift
+class Solution {
+ func permute(_ nums: [Int]) -> [[Int]] {
+ var perms: [[Int]] = [[]]
+
+ for num in nums {
+ var newPerms = [[Int]]()
+ for p in perms {
+ for i in 0...p.count {
+ var pCopy = p
+ pCopy.insert(num, at: i)
+ newPerms.append(pCopy)
+ }
+ }
+ perms = newPerms
+ }
+
+ return perms
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -501,6 +546,35 @@ class Solution {
}
```
+```swift
+class Solution {
+ func permute(_ nums: [Int]) -> [[Int]] {
+ var res = [[Int]]()
+ var pick = [Bool](repeating: false, count: nums.count)
+
+ func backtrack(_ perm: inout [Int]) {
+ if perm.count == nums.count {
+ res.append(perm)
+ return
+ }
+ for i in 0.. [[Int]] {
+ var res = [[Int]]()
+
+ func backtrack(_ perm: inout [Int], _ mask: Int) {
+ if perm.count == nums.count {
+ res.append(perm)
+ return
+ }
+ for i in 0.. [[Int]] {
+ var res = [[Int]]()
+ var nums = nums
+
+ func backtrack(_ idx: Int) {
+ if idx == nums.count {
+ res.append(nums)
+ return
+ }
+ for i in idx.. [Int] {
+ if digits.isEmpty {
+ return [1]
+ }
+
+ var digits = digits
+ if digits[digits.count - 1] < 9 {
+ digits[digits.count - 1] += 1
+ return digits
+ } else {
+ return plusOne(Array(digits.dropLast())) + [0]
+ }
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -341,6 +359,35 @@ class Solution {
}
```
+```swift
+class Solution {
+ func plusOne(_ digits: [Int]) -> [Int] {
+ var digits = digits
+ var one = 1
+ var i = 0
+ digits.reverse()
+
+ while one > 0 {
+ if i < digits.count {
+ if digits[i] == 9 {
+ digits[i] = 0
+ } else {
+ digits[i] += 1
+ one = 0
+ }
+ } else {
+ digits.append(one)
+ one = 0
+ }
+ i += 1
+ }
+
+ digits.reverse()
+ return digits
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -476,6 +523,25 @@ class Solution {
}
```
+```swift
+class Solution {
+ func plusOne(_ digits: [Int]) -> [Int] {
+ var digits = digits
+ let n = digits.count
+
+ for i in stride(from: n - 1, through: 0, by: -1) {
+ if digits[i] < 9 {
+ digits[i] += 1
+ return digits
+ }
+ digits[i] = 0
+ }
+
+ return [1] + digits
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/pow-x-n.md b/articles/pow-x-n.md
index 341e3ae9d..50beeb0f4 100644
--- a/articles/pow-x-n.md
+++ b/articles/pow-x-n.md
@@ -139,6 +139,25 @@ class Solution {
}
```
+```swift
+class Solution {
+ func myPow(_ x: Double, _ n: Int) -> Double {
+ if x == 0 {
+ return 0
+ }
+ if n == 0 {
+ return 1
+ }
+
+ var res: Double = 1
+ for _ in 0..= 0 ? res : 1 / res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -320,12 +339,33 @@ class Solution {
}
```
+```swift
+class Solution {
+ func myPow(_ x: Double, _ n: Int) -> Double {
+ func helper(_ x: Double, _ n: Int) -> Double {
+ if x == 0 {
+ return 0
+ }
+ if n == 0 {
+ return 1
+ }
+
+ let res = helper(x * x, n / 2)
+ return n % 2 == 0 ? res : x * res
+ }
+
+ let res = helper(x, abs(n))
+ return n >= 0 ? res : 1 / res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(\log n)$
-* Space complexity: $O(\log n)$
+* Space complexity: $O(\log n)$ for recursion stack.
---
@@ -501,6 +541,33 @@ class Solution {
}
```
+```swift
+class Solution {
+ func myPow(_ x: Double, _ n: Int) -> Double {
+ if x == 0 {
+ return 0
+ }
+ if n == 0 {
+ return 1
+ }
+
+ var res: Double = 1
+ var base = x
+ var power = abs(n)
+
+ while power > 0 {
+ if power & 1 == 1 {
+ res *= base
+ }
+ base *= base
+ power >>= 1
+ }
+
+ return n >= 0 ? res : 1 / res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/products-of-array-discluding-self.md b/articles/products-of-array-discluding-self.md
index 1a74a5c68..1370fac97 100644
--- a/articles/products-of-array-discluding-self.md
+++ b/articles/products-of-array-discluding-self.md
@@ -142,12 +142,37 @@ class Solution {
}
```
+```swift
+class Solution {
+ func productExceptSelf(_ nums: [Int]) -> [Int] {
+ let n = nums.count
+ var res = [Int](repeating: 0, count: n)
+
+ for i in 0.. [Int] {
+ var prod = 1
+ var zeroCount = 0
+
+ for num in nums {
+ if num != 0 {
+ prod *= num
+ } else {
+ zeroCount += 1
+ }
+ }
+
+ if zeroCount > 1 {
+ return [Int](repeating: 0, count: nums.count)
+ }
+
+ var res = [Int](repeating: 0, count: nums.count)
+ for (i, num) in nums.enumerated() {
+ if zeroCount > 0 {
+ res[i] = num == 0 ? prod : 0
+ } else {
+ res[i] = prod / num
+ }
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(n)$
-* Space complexity: $O(1)$ since the output array is excluded from space analysis.
+* Space complexity:
+ * $O(1)$ extra space.
+ * $O(n)$ space for the output array.
---
@@ -533,6 +592,34 @@ class Solution {
}
```
+```swift
+class Solution {
+ func productExceptSelf(_ nums: [Int]) -> [Int] {
+ let n = nums.count
+ var res = [Int](repeating: 0, count: n)
+ var pref = [Int](repeating: 0, count: n)
+ var suff = [Int](repeating: 0, count: n)
+
+ pref[0] = 1
+ suff[n - 1] = 1
+
+ for i in 1.. [Int] {
+ var res = [Int](repeating: 1, count: nums.count)
+
+ var prefix = 1
+ for i in 0.. [String] {
+ var adj = [String: [String]]()
+ for ticket in tickets {
+ adj[ticket[0], default: []].append(ticket[1])
+ }
+
+ for key in adj.keys {
+ adj[key]?.sort()
+ }
+
+ var res = ["JFK"]
+
+ func dfs(_ src: String) -> Bool {
+ if res.count == tickets.count + 1 {
+ return true
+ }
+ guard let destinations = adj[src] else {
+ return false
+ }
+
+ var temp = destinations
+ for i in 0.. [String] {
+ var adj = [String: [String]]()
+ for ticket in tickets.sorted(by: { $0[1] > $1[1] }) {
+ adj[ticket[0], default: []].append(ticket[1])
+ }
+
+ var res = [String]()
+
+ func dfs(_ src: String) {
+ while let destinations = adj[src], !destinations.isEmpty {
+ let dst = adj[src]!.removeLast()
+ dfs(dst)
+ }
+ res.append(src)
+ }
+
+ dfs("JFK")
+ return res.reversed()
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -718,6 +782,31 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findItinerary(_ tickets: [[String]]) -> [String] {
+ var adj = [String: [String]]()
+ for ticket in tickets.sorted(by: { $0[1] > $1[1] }) {
+ adj[ticket[0], default: []].append(ticket[1])
+ }
+
+ var stack = ["JFK"]
+ var res = [String]()
+
+ while !stack.isEmpty {
+ let curr = stack.last!
+ if adj[curr] == nil || adj[curr]!.isEmpty {
+ res.append(stack.removeLast())
+ } else {
+ stack.append(adj[curr]!.removeLast())
+ }
+ }
+
+ return res.reversed()
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/redundant-connection.md b/articles/redundant-connection.md
index 81a67ff84..154493da7 100644
--- a/articles/redundant-connection.md
+++ b/articles/redundant-connection.md
@@ -247,6 +247,45 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findRedundantConnection(_ edges: [[Int]]) -> [Int] {
+ let n = edges.count
+ var adj = Array(repeating: [Int](), count: n + 1)
+
+ func dfs(_ node: Int, _ par: Int, _ visit: inout [Bool]) -> Bool {
+ if visit[node] {
+ return true
+ }
+
+ visit[node] = true
+ for nei in adj[node] {
+ if nei == par {
+ continue
+ }
+ if dfs(nei, node, &visit) {
+ return true
+ }
+ }
+ return false
+ }
+
+ for edge in edges {
+ let u = edge[0]
+ let v = edge[1]
+ adj[u].append(v)
+ adj[v].append(u)
+ var visit = Array(repeating: false, count: n + 1)
+
+ if dfs(u, -1, &visit) {
+ return [u, v]
+ }
+ }
+ return []
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -606,6 +645,62 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findRedundantConnection(_ edges: [[Int]]) -> [Int] {
+ let n = edges.count
+ var adj = Array(repeating: [Int](), count: n + 1)
+
+ for edge in edges {
+ let u = edge[0]
+ let v = edge[1]
+ adj[u].append(v)
+ adj[v].append(u)
+ }
+
+ var visit = Array(repeating: false, count: n + 1)
+ var cycle = Set()
+ var cycleStart = -1
+
+ func dfs(_ node: Int, _ par: Int) -> Bool {
+ if visit[node] {
+ cycleStart = node
+ return true
+ }
+
+ visit[node] = true
+ for nei in adj[node] {
+ if nei == par {
+ continue
+ }
+ if dfs(nei, node) {
+ if cycleStart != -1 {
+ cycle.insert(node)
+ }
+ if node == cycleStart {
+ cycleStart = -1
+ }
+ return true
+ }
+ }
+ return false
+ }
+
+ dfs(1, -1)
+
+ for edge in edges.reversed() {
+ let u = edge[0]
+ let v = edge[1]
+ if cycle.contains(u) && cycle.contains(v) {
+ return [u, v]
+ }
+ }
+
+ return []
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -895,6 +990,52 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findRedundantConnection(_ edges: [[Int]]) -> [Int] {
+ let n = edges.count
+ var indegree = Array(repeating: 0, count: n + 1)
+ var adj = Array(repeating: [Int](), count: n + 1)
+
+ for edge in edges {
+ let u = edge[0]
+ let v = edge[1]
+ adj[u].append(v)
+ adj[v].append(u)
+ indegree[u] += 1
+ indegree[v] += 1
+ }
+
+ var queue = Deque()
+ for i in 1...n {
+ if indegree[i] == 1 {
+ queue.append(i)
+ }
+ }
+
+ while !queue.isEmpty {
+ let node = queue.popFirst()!
+ indegree[node] -= 1
+ for nei in adj[node] {
+ indegree[nei] -= 1
+ if indegree[nei] == 1 {
+ queue.append(nei)
+ }
+ }
+ }
+
+ for edge in edges.reversed() {
+ let u = edge[0]
+ let v = edge[1]
+ if indegree[u] == 2 && indegree[v] > 0 {
+ return [u, v]
+ }
+ }
+ return []
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1212,6 +1353,50 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findRedundantConnection(_ edges: [[Int]]) -> [Int] {
+ var par = Array(0...edges.count)
+ var rank = Array(repeating: 1, count: edges.count + 1)
+
+ func find(_ n: Int) -> Int {
+ var p = par[n]
+ while p != par[p] {
+ par[p] = par[par[p]]
+ p = par[p]
+ }
+ return p
+ }
+
+ func union(_ n1: Int, _ n2: Int) -> Bool {
+ let p1 = find(n1)
+ let p2 = find(n2)
+
+ if p1 == p2 {
+ return false
+ }
+ if rank[p1] > rank[p2] {
+ par[p2] = p1
+ rank[p1] += rank[p2]
+ } else {
+ par[p1] = p2
+ rank[p2] += rank[p1]
+ }
+ return true
+ }
+
+ for edge in edges {
+ let n1 = edge[0]
+ let n2 = edge[1]
+ if !union(n1, n2) {
+ return [n1, n2]
+ }
+ }
+ return []
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/regular-expression-matching.md b/articles/regular-expression-matching.md
index 31b2a26a4..fd4bfda86 100644
--- a/articles/regular-expression-matching.md
+++ b/articles/regular-expression-matching.md
@@ -184,6 +184,35 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isMatch(_ s: String, _ p: String) -> Bool {
+ let sArr = Array(s), pArr = Array(p)
+ let m = sArr.count, n = pArr.count
+
+ func dfs(_ i: Int, _ j: Int) -> Bool {
+ if j == n {
+ return i == m
+ }
+
+ let match = i < m && (sArr[i] == pArr[j] || pArr[j] == ".")
+
+ if j + 1 < n && pArr[j + 1] == "*" {
+ return dfs(i, j + 2) || (match && dfs(i + 1, j))
+ }
+
+ if match {
+ return dfs(i + 1, j + 1)
+ }
+
+ return false
+ }
+
+ return dfs(0, 0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -432,6 +461,42 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isMatch(_ s: String, _ p: String) -> Bool {
+ let sArr = Array(s), pArr = Array(p)
+ let m = sArr.count, n = pArr.count
+ var cache = [[Bool?]](repeating: [Bool?](repeating: nil, count: n + 1), count: m + 1)
+
+ func dfs(_ i: Int, _ j: Int) -> Bool {
+ if j == n {
+ return i == m
+ }
+ if let cached = cache[i][j] {
+ return cached
+ }
+
+ let match = i < m && (sArr[i] == pArr[j] || pArr[j] == ".")
+
+ if j + 1 < n && pArr[j + 1] == "*" {
+ cache[i][j] = dfs(i, j + 2) || (match && dfs(i + 1, j))
+ return cache[i][j]!
+ }
+
+ if match {
+ cache[i][j] = dfs(i + 1, j + 1)
+ return cache[i][j]!
+ }
+
+ cache[i][j] = false
+ return false
+ }
+
+ return dfs(0, 0)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -635,6 +700,34 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isMatch(_ s: String, _ p: String) -> Bool {
+ let sArr = Array(s), pArr = Array(p)
+ let m = sArr.count, n = pArr.count
+ var dp = Array(repeating: Array(repeating: false, count: n + 1), count: m + 1)
+ dp[m][n] = true
+
+ for i in stride(from: m, through: 0, by: -1) {
+ for j in stride(from: n - 1, through: 0, by: -1) {
+ let match = i < m && (sArr[i] == pArr[j] || pArr[j] == ".")
+
+ if j + 1 < n && pArr[j + 1] == "*" {
+ dp[i][j] = dp[i][j + 2]
+ if match {
+ dp[i][j] = dp[i][j] || dp[i + 1][j]
+ }
+ } else if match {
+ dp[i][j] = dp[i + 1][j + 1]
+ }
+ }
+ }
+
+ return dp[0][0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -862,6 +955,38 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isMatch(_ s: String, _ p: String) -> Bool {
+ let sArr = Array(s), pArr = Array(p)
+ var dp = Array(repeating: false, count: pArr.count + 1)
+ dp[pArr.count] = true
+
+ for i in stride(from: sArr.count, through: 0, by: -1) {
+ var nextDp = Array(repeating: false, count: pArr.count + 1)
+ nextDp[pArr.count] = (i == sArr.count)
+
+ for j in stride(from: pArr.count - 1, through: 0, by: -1) {
+ let match = i < sArr.count && (sArr[i] == pArr[j] || pArr[j] == ".")
+
+ if j + 1 < pArr.count && pArr[j + 1] == "*" {
+ nextDp[j] = nextDp[j + 2]
+ if match {
+ nextDp[j] = nextDp[j] || dp[j]
+ }
+ } else if match {
+ nextDp[j] = dp[j + 1]
+ }
+ }
+
+ dp = nextDp
+ }
+
+ return dp[0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -1096,6 +1221,39 @@ class Solution {
}
```
+```swift
+class Solution {
+ func isMatch(_ s: String, _ p: String) -> Bool {
+ let sArr = Array(s)
+ let pArr = Array(p)
+ var dp = [Bool](repeating: false, count: pArr.count + 1)
+ dp[pArr.count] = true
+
+ for i in stride(from: sArr.count, through: 0, by: -1) {
+ var dp1 = dp[pArr.count]
+ dp[pArr.count] = (i == sArr.count)
+
+ for j in stride(from: pArr.count - 1, through: 0, by: -1) {
+ let match = i < sArr.count && (sArr[i] == pArr[j] || pArr[j] == ".")
+ var res = false
+ if j + 1 < pArr.count && pArr[j + 1] == "*" {
+ res = dp[j + 2]
+ if match {
+ res = res || dp[j]
+ }
+ } else if match {
+ res = dp1
+ }
+ dp1 = dp[j]
+ dp[j] = res
+ }
+ }
+
+ return dp[0]
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/remove-node-from-end-of-linked-list.md b/articles/remove-node-from-end-of-linked-list.md
index 141817504..ee936f416 100644
--- a/articles/remove-node-from-end-of-linked-list.md
+++ b/articles/remove-node-from-end-of-linked-list.md
@@ -216,6 +216,38 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {
+ var nodes: [ListNode] = []
+ var cur = head
+
+ while cur != nil {
+ nodes.append(cur!)
+ cur = cur?.next
+ }
+
+ let removeIndex = nodes.count - n
+ if removeIndex == 0 {
+ return head?.next
+ }
+
+ nodes[removeIndex - 1].next = nodes[removeIndex].next
+ return head
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -490,6 +522,44 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {
+ var N = 0
+ var cur = head
+ while cur != nil {
+ N += 1
+ cur = cur?.next
+ }
+
+ let removeIndex = N - n
+ if removeIndex == 0 {
+ return head?.next
+ }
+
+ cur = head
+ for i in 0..<(N - 1) {
+ if (i + 1) == removeIndex {
+ cur?.next = cur?.next?.next
+ break
+ }
+ cur = cur?.next
+ }
+ return head
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -723,12 +793,44 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func rec(_ head: ListNode?, _ n: inout Int) -> ListNode? {
+ if head == nil {
+ return nil
+ }
+
+ head?.next = rec(head?.next, &n)
+ n -= 1
+ if n == 0 {
+ return head?.next
+ }
+ return head
+ }
+
+ func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {
+ var n = n
+ return rec(head, &n)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
* Time complexity: $O(N)$
-* Space complexity: $O(N)$
+* Space complexity: $O(N)$ for recursion stack.
---
@@ -964,6 +1066,40 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {
+ let dummy = ListNode(0, head)
+ var left: ListNode? = dummy
+ var right: ListNode? = head
+ var n = n
+
+ while n > 0 {
+ right = right?.next
+ n -= 1
+ }
+
+ while right != nil {
+ left = left?.next
+ right = right?.next
+ }
+
+ left?.next = left?.next?.next
+ return dummy.next
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/reorder-linked-list.md b/articles/reorder-linked-list.md
index 399860a22..75e0ef82c 100644
--- a/articles/reorder-linked-list.md
+++ b/articles/reorder-linked-list.md
@@ -260,6 +260,47 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func reorderList(_ head: ListNode?) {
+ if head == nil {
+ return
+ }
+
+ var nodes: [ListNode] = []
+ var cur = head
+
+ while cur != nil {
+ nodes.append(cur!)
+ cur = cur?.next
+ }
+
+ var i = 0, j = nodes.count - 1
+ while i < j {
+ nodes[i].next = nodes[j]
+ i += 1
+ if i >= j {
+ break
+ }
+ nodes[j].next = nodes[i]
+ j -= 1
+ }
+
+ nodes[i].next = nil
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -286,10 +327,11 @@ class Solution:
def rec(root: ListNode, cur: ListNode) -> ListNode:
if not cur:
return root
- root = rec(root, cur.next)
+ root = rec(root, cur.next)
if not root:
return None
+
tmp = None
if root == cur or root.next == cur:
cur.next = None
@@ -297,8 +339,9 @@ class Solution:
tmp = root.next
root.next = cur
cur.next = tmp
+
return tmp
-
+
head = rec(head, head.next)
```
@@ -323,10 +366,12 @@ public class Solution {
if (cur == null) {
return root;
}
+
root = rec(root, cur.next);
if (root == null) {
return null;
}
+
ListNode tmp = null;
if (root == cur || root.next == cur) {
cur.next = null;
@@ -335,6 +380,7 @@ public class Solution {
root.next = cur;
cur.next = tmp;
}
+
return tmp;
}
}
@@ -363,10 +409,12 @@ private:
if (cur == nullptr) {
return root;
}
+
root = rec(root, cur->next);
if (root == nullptr) {
return nullptr;
}
+
ListNode* tmp = nullptr;
if (root == cur || root->next == cur) {
cur->next = nullptr;
@@ -375,6 +423,7 @@ private:
root->next = cur;
cur->next = tmp;
}
+
return tmp;
}
};
@@ -409,10 +458,12 @@ class Solution {
if (cur === null) {
return root;
}
+
root = this.rec(root, cur.next);
if (root === null) {
return null;
}
+
let tmp = null;
if (root === cur || root.next === cur) {
cur.next = null;
@@ -421,6 +472,7 @@ class Solution {
root.next = cur;
cur.next = tmp;
}
+
return tmp;
}
}
@@ -448,10 +500,12 @@ public class Solution {
if (cur == null) {
return root;
}
+
root = Rec(root, cur.next);
if (root == null) {
return null;
}
+
ListNode tmp = null;
if (root == cur || root.next == cur) {
cur.next = null;
@@ -460,6 +514,7 @@ public class Solution {
root.next = cur;
cur.next = tmp;
}
+
return tmp;
}
}
@@ -483,11 +538,12 @@ func reorderList(head *ListNode) {
if cur == nil {
return root
}
- root = rec(root, cur.Next)
+ root = rec(root, cur.Next)
if root == nil {
return nil
}
+
var tmp *ListNode
if root == cur || root.Next == cur {
cur.Next = nil
@@ -496,6 +552,7 @@ func reorderList(head *ListNode) {
root.Next = cur
cur.Next = tmp
}
+
return tmp
}
@@ -521,11 +578,12 @@ class Solution {
if (cur == null) {
return root
}
- var updatedRoot = rec(root, cur.next)
+ var updatedRoot = rec(root, cur.next)
if (updatedRoot == null) {
return null
}
+
var tmp: ListNode? = null
if (updatedRoot == cur || updatedRoot?.next == cur) {
cur.next = null
@@ -534,6 +592,7 @@ class Solution {
updatedRoot.next = cur
cur.next = tmp
}
+
return tmp
}
@@ -542,6 +601,46 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func reorderList(_ head: ListNode?) {
+ func rec(_ root: ListNode?, _ cur: ListNode?) -> ListNode? {
+ if cur == nil {
+ return root
+ }
+
+ var root = rec(root, cur?.next)
+ if root == nil {
+ return nil
+ }
+
+ var tmp: ListNode? = nil
+ if root === cur || root?.next === cur {
+ cur?.next = nil
+ } else {
+ tmp = root?.next
+ root?.next = cur
+ cur?.next = tmp
+ }
+
+ return tmp
+ }
+
+ rec(head, head?.next)
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -852,6 +951,51 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func reorderList(_ head: ListNode?) {
+ var slow = head, fast = head?.next
+ while fast != nil && fast?.next != nil {
+ slow = slow?.next
+ fast = fast?.next?.next
+ }
+
+ var second = slow?.next
+ var prev: ListNode? = nil
+ slow?.next = nil
+
+ while second != nil {
+ let tmp = second?.next
+ second?.next = prev
+ prev = second
+ second = tmp
+ }
+
+ var first = head
+ second = prev
+
+ while second != nil {
+ let tmp1 = first?.next
+ let tmp2 = second?.next
+ first?.next = second
+ second?.next = tmp1
+ first = tmp1
+ second = tmp2
+ }
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/reverse-a-linked-list.md b/articles/reverse-a-linked-list.md
index 98f5ee98d..3a205a543 100644
--- a/articles/reverse-a-linked-list.md
+++ b/articles/reverse-a-linked-list.md
@@ -200,6 +200,35 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func reverseList(_ head: ListNode?) -> ListNode? {
+ if head == nil {
+ return nil
+ }
+
+ var newHead = head
+ if head?.next != nil {
+ newHead = reverseList(head?.next)
+ head?.next?.next = head
+ }
+ head?.next = nil
+
+ return newHead
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -397,6 +426,33 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func reverseList(_ head: ListNode?) -> ListNode? {
+ var prev: ListNode? = nil
+ var curr = head
+
+ while curr != nil {
+ let temp = curr?.next
+ curr?.next = prev
+ prev = curr
+ curr = temp
+ }
+ return prev
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/reverse-bits.md b/articles/reverse-bits.md
index d5267bf19..84cbe88ce 100644
--- a/articles/reverse-bits.md
+++ b/articles/reverse-bits.md
@@ -162,6 +162,30 @@ class Solution {
}
```
+```swift
+class Solution {
+ func reverseBits(_ n: Int) -> Int {
+ var binary = ""
+ for i in 0..<32 {
+ if (n & (1 << i)) != 0 {
+ binary += "1"
+ } else {
+ binary += "0"
+ }
+ }
+
+ var res = 0
+ for (i, bit) in binary.reversed().enumerated() {
+ if bit == "1" {
+ res |= (1 << i)
+ }
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -266,6 +290,20 @@ class Solution {
}
```
+```swift
+class Solution {
+ func reverseBits(_ n: Int) -> Int {
+ var res = 0
+ var num = n
+ for i in 0..<32 {
+ let bit = (num >> i) & 1
+ res |= (bit << (31 - i))
+ }
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -378,6 +416,20 @@ class Solution {
}
```
+```swift
+class Solution {
+ func reverseBits(_ n: Int) -> Int {
+ var res = n
+ res = (res >> 16) | (res << 16) & 0xFFFFFFFF
+ res = ((res & 0xff00ff00) >> 8) | ((res & 0x00ff00ff) << 8)
+ res = ((res & 0xf0f0f0f0) >> 4) | ((res & 0x0f0f0f0f) << 4)
+ res = ((res & 0xcccccccc) >> 2) | ((res & 0x33333333) << 2)
+ res = ((res & 0xaaaaaaaa) >> 1) | ((res & 0x55555555) << 1)
+ return res & 0xFFFFFFFF
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/reverse-integer.md b/articles/reverse-integer.md
index f6d060a33..c388a821f 100644
--- a/articles/reverse-integer.md
+++ b/articles/reverse-integer.md
@@ -147,6 +147,25 @@ class Solution {
}
```
+```swift
+class Solution {
+ func reverse(_ x: Int) -> Int {
+ let org = x
+ var x = abs(x)
+ var res = Int(String(String(x).reversed()))!
+
+ if org < 0 {
+ res *= -1
+ }
+ if res < Int32.min || res > Int32.max {
+ return 0
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -310,6 +329,28 @@ class Solution {
}
```
+```swift
+class Solution {
+ func reverse(_ x: Int) -> Int {
+ func rec(_ n: Int, _ rev: Int) -> Int {
+ if n == 0 {
+ return rev
+ }
+ return rec(n / 10, rev * 10 + n % 10)
+ }
+
+ let sign = x < 0 ? -1 : 1
+ let reversedNum = rec(abs(x), 0) * sign
+
+ if reversedNum < Int32.min || reversedNum > Int32.max {
+ return 0
+ }
+
+ return reversedNum
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -489,6 +530,33 @@ class Solution {
}
```
+```swift
+class Solution {
+ func reverse(_ x: Int) -> Int {
+ let MIN = Int32.min
+ let MAX = Int32.max
+
+ var res = 0
+ var num = x
+
+ while num != 0 {
+ let digit = num % 10
+ num /= 10
+
+ if res > MAX / 10 || (res == MAX / 10 && digit > MAX % 10) {
+ return 0
+ }
+ if res < MIN / 10 || (res == MIN / 10 && digit < MIN % 10) {
+ return 0
+ }
+ res = res * 10 + digit
+ }
+
+ return res
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/reverse-nodes-in-k-group.md b/articles/reverse-nodes-in-k-group.md
index ad54de13e..f5836142d 100644
--- a/articles/reverse-nodes-in-k-group.md
+++ b/articles/reverse-nodes-in-k-group.md
@@ -251,6 +251,47 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func reverseKGroup(_ head: ListNode?, _ k: Int) -> ListNode? {
+ var cur = head
+ var group = 0
+
+ while cur != nil && group < k {
+ cur = cur!.next
+ group += 1
+ }
+
+ if group == k {
+ cur = reverseKGroup(cur, k)
+
+ var tempHead = head
+ while group > 0 {
+ let tmp = tempHead!.next
+ tempHead!.next = cur
+ cur = tempHead
+ tempHead = tmp
+ group -= 1
+ }
+
+ return cur
+ }
+
+ return head
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -603,6 +644,57 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public var val: Int
+ * public var next: ListNode?
+ * public init() { self.val = 0; self.next = nil; }
+ * public init(_ val: Int) { self.val = val; self.next = nil; }
+ * public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
+ * }
+ */
+class Solution {
+ func reverseKGroup(_ head: ListNode?, _ k: Int) -> ListNode? {
+ let dummy = ListNode(0, head)
+ var groupPrev: ListNode? = dummy
+
+ while true {
+ guard let kth = getKth(groupPrev, k) else {
+ break
+ }
+ let groupNext = kth.next
+
+ var prev: ListNode? = kth.next
+ var curr = groupPrev?.next
+
+ while curr !== groupNext {
+ let tmp = curr?.next
+ curr?.next = prev
+ prev = curr
+ curr = tmp
+ }
+
+ let tmp = groupPrev?.next
+ groupPrev?.next = kth
+ groupPrev = tmp
+ }
+ return dummy.next
+ }
+
+ private func getKth(_ curr: ListNode?, _ k: Int) -> ListNode? {
+ var curr = curr
+ var k = k
+ while curr != nil && k > 0 {
+ curr = curr?.next
+ k -= 1
+ }
+ return curr
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/rotate-matrix.md b/articles/rotate-matrix.md
index 2f050d984..c7ea787f1 100644
--- a/articles/rotate-matrix.md
+++ b/articles/rotate-matrix.md
@@ -145,6 +145,27 @@ class Solution {
}
```
+```swift
+class Solution {
+ func rotate(_ matrix: inout [[Int]]) {
+ let n = matrix.count
+ var rotated = Array(repeating: Array(repeating: 0, count: n), count: n)
+
+ for i in 0.. Int {
+ var grid = grid
+ var queue = Deque<(Int, Int)>()
+ var fresh = 0
+ var time = 0
+
+ let ROWS = grid.count
+ let COLS = grid[0].count
+
+ for r in 0.. 0 && !queue.isEmpty {
+ let length = queue.count
+ for _ in 0..= 0 && row < ROWS && col >= 0 && col < COLS && grid[row][col] == 1 {
+ grid[row][col] = 2
+ queue.append((row, col))
+ fresh -= 1
+ }
+ }
+ }
+ time += 1
+ }
+
+ return fresh == 0 ? time : -1
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -704,6 +752,64 @@ class Solution {
}
```
+```swift
+class Solution {
+ func orangesRotting(_ grid: [[Int]]) -> Int {
+ var grid = grid
+ let ROWS = grid.count
+ let COLS = grid[0].count
+ var fresh = 0
+ var time = 0
+
+ for r in 0.. 0 {
+ var flag = false
+ for r in 0..= 0 && row < ROWS && col >= 0 &&
+ col < COLS && grid[row][col] == 1) {
+ grid[row][col] = 3
+ fresh -= 1
+ flag = true
+ }
+ }
+ }
+ }
+ }
+
+ if !flag {
+ return -1
+ }
+
+ for r in 0.. Bool {
+ if p == nil && q == nil {
+ return true
+ }
+ if let p = p, let q = q, p.val == q.val {
+ return isSameTree(p.left, q.left) && isSameTree(p.right, q.right)
+ } else {
+ return false
+ }
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -444,6 +474,45 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func isSameTree(_ p: TreeNode?, _ q: TreeNode?) -> Bool {
+ var stack: [(TreeNode?, TreeNode?)] = [(p, q)]
+
+ while !stack.isEmpty {
+ let (node1, node2) = stack.removeLast()
+
+ if node1 == nil && node2 == nil {
+ continue
+ }
+ if node1 == nil || node2 == nil || node1!.val != node2!.val {
+ return false
+ }
+
+ stack.append((node1!.right, node2!.right))
+ stack.append((node1!.left, node2!.left))
+ }
+
+ return true
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -742,6 +811,51 @@ class Solution {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init() { self.val = 0; self.left = nil; self.right = nil; }
+ * public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
+ * public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
+ * self.val = val
+ * self.left = left
+ * self.right = right
+ * }
+ * }
+ */
+class Solution {
+ func isSameTree(_ p: TreeNode?, _ q: TreeNode?) -> Bool {
+ var q1 = Deque()
+ var q2 = Deque()
+ q1.append(p)
+ q2.append(q)
+
+ while !q1.isEmpty && !q2.isEmpty {
+ let nodeP = q1.removeFirst()
+ let nodeQ = q2.removeFirst()
+
+ if nodeP == nil && nodeQ == nil {
+ continue
+ }
+ if nodeP == nil || nodeQ == nil || nodeP!.val != nodeQ!.val {
+ return false
+ }
+
+ q1.append(nodeP!.left)
+ q1.append(nodeP!.right)
+ q2.append(nodeQ!.left)
+ q2.append(nodeQ!.right)
+ }
+
+ return true
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/search-2d-matrix.md b/articles/search-2d-matrix.md
index 722cbe2b6..45181e5df 100644
--- a/articles/search-2d-matrix.md
+++ b/articles/search-2d-matrix.md
@@ -106,6 +106,21 @@ class Solution {
}
```
+```swift
+class Solution {
+ func searchMatrix(_ matrix: [[Int]], _ target: Int) -> Bool {
+ for r in 0.. Bool {
+ let m = matrix.count
+ let n = matrix[0].count
+ var r = 0, c = n - 1
+
+ while r < m && c >= 0 {
+ if matrix[r][c] > target {
+ c -= 1
+ } else if matrix[r][c] < target {
+ r += 1
+ } else {
+ return true
+ }
+ }
+ return false
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -546,6 +582,44 @@ class Solution {
}
```
+```swift
+class Solution {
+ func searchMatrix(_ matrix: [[Int]], _ target: Int) -> Bool {
+ let ROWS = matrix.count
+ let COLS = matrix[0].count
+
+ var top = 0, bot = ROWS - 1
+ while top <= bot {
+ let row = (top + bot) / 2
+ if target > matrix[row][COLS - 1] {
+ top = row + 1
+ } else if target < matrix[row][0] {
+ bot = row - 1
+ } else {
+ break
+ }
+ }
+
+ if !(top <= bot) {
+ return false
+ }
+ let row = (top + bot) / 2
+ var l = 0, r = COLS - 1
+ while l <= r {
+ let m = (l + r) / 2
+ if target > matrix[row][m] {
+ l = m + 1
+ } else if target < matrix[row][m] {
+ r = m - 1
+ } else {
+ return true
+ }
+ }
+ return false
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -718,6 +792,31 @@ class Solution {
}
```
+```swift
+class Solution {
+ func searchMatrix(_ matrix: [[Int]], _ target: Int) -> Bool {
+ let ROWS = matrix.count
+ let COLS = matrix[0].count
+
+ var l = 0, r = ROWS * COLS - 1
+ while l <= r {
+ let m = l + (r - l) / 2
+ let row = m / COLS
+ let col = m % COLS
+
+ if target > matrix[row][col] {
+ l = m + 1
+ } else if target < matrix[row][col] {
+ r = m - 1
+ } else {
+ return true
+ }
+ }
+ return false
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/search-for-word-ii.md b/articles/search-for-word-ii.md
index d304ea983..519307f04 100644
--- a/articles/search-for-word-ii.md
+++ b/articles/search-for-word-ii.md
@@ -282,6 +282,53 @@ class Solution {
}
```
+```swift
+class Solution {
+ func findWords(_ board: [[Character]], _ words: [String]) -> [String] {
+ let ROWS = board.count
+ let COLS = board[0].count
+ var res: [String] = []
+ var board = board
+
+ func backtrack(_ r: Int, _ c: Int, _ i: Int, _ word: [Character]) -> Bool {
+ if i == word.count {
+ return true
+ }
+ if r < 0 || c < 0 || r >= ROWS || c >= COLS || board[r][c] != word[i] {
+ return false
+ }
+
+ board[r][c] = "*"
+ let ret = backtrack(r + 1, c, i + 1, word) ||
+ backtrack(r - 1, c, i + 1, word) ||
+ backtrack(r, c + 1, i + 1, word) ||
+ backtrack(r, c - 1, i + 1, word)
+ board[r][c] = word[i]
+ return ret
+ }
+
+ for word in words {
+ var flag = false
+ let wordArray = Array(word)
+ for r in 0.. children;
boolean isWord;
@@ -743,6 +790,68 @@ class Solution {
}
```
+```swift
+class TrieNode {
+ var children: [Character: TrieNode] = [:]
+ var isWord: Bool = false
+
+ func addWord(_ word: String) {
+ var current = self
+ for char in word {
+ if current.children[char] == nil {
+ current.children[char] = TrieNode()
+ }
+ current = current.children[char]!
+ }
+ current.isWord = true
+ }
+}
+
+class Solution {
+ func findWords(_ board: [[Character]], _ words: [String]) -> [String] {
+ let root = TrieNode()
+ for word in words {
+ root.addWord(word)
+ }
+
+ let ROWS = board.count
+ let COLS = board[0].count
+ var result = Set()
+ var visited = Set<[Int]>()
+
+ func dfs(_ r: Int, _ c: Int, _ node: TrieNode, _ word: String) {
+ if r < 0 || c < 0 || r >= ROWS || c >= COLS ||
+ visited.contains([r, c]) || node.children[board[r][c]] == nil {
+ return
+ }
+
+ visited.insert([r, c])
+ let nextNode = node.children[board[r][c]]!
+ let newWord = word + String(board[r][c])
+
+ if nextNode.isWord {
+ result.insert(newWord)
+ }
+
+ dfs(r + 1, c, nextNode, newWord)
+ dfs(r - 1, c, nextNode, newWord)
+ dfs(r, c + 1, nextNode, newWord)
+ dfs(r, c - 1, nextNode, newWord)
+
+ visited.remove([r, c])
+ }
+
+ for r in 0.. [String] {
+ let root = TrieNode()
+ for i in 0.. Int {
+ return Int(c.asciiValue! - Character("a").asciiValue!)
+ }
+
+ func dfs(_ r: Int, _ c: Int, _ node: TrieNode) {
+ if r < 0 || c < 0 || r >= ROWS || c >= COLS ||
+ boardCopy[r][c] == "*" ||
+ node.children[getIndex(boardCopy[r][c])] == nil {
+ return
+ }
+
+ let tmp = boardCopy[r][c]
+ boardCopy[r][c] = "*"
+ let prev = node
+ let nextNode = node.children[getIndex(tmp)]!
+
+ if nextNode.idx != -1 {
+ res.append(words[nextNode.idx])
+ nextNode.idx = -1
+ nextNode.refs -= 1
+ if nextNode.refs == 0 {
+ prev.children[getIndex(tmp)] = nil
+ boardCopy[r][c] = tmp
+ return
+ }
+ }
+
+ dfs(r + 1, c, nextNode)
+ dfs(r - 1, c, nextNode)
+ dfs(r, c + 1, nextNode)
+ dfs(r, c - 1, nextNode)
+
+ boardCopy[r][c] = tmp
+ }
+
+ for r in 0.. Bool {
+ let ROWS = board.count
+ let COLS = board[0].count
+ var path = Set<[Int]>()
+ let wordArray = Array(word)
+
+ func dfs(_ r: Int, _ c: Int, _ i: Int) -> Bool {
+ if i == wordArray.count {
+ return true
+ }
+ if (r < 0 || c < 0 || r >= ROWS || c >= COLS ||
+ board[r][c] != wordArray[i] || path.contains([r, c])) {
+ return false
+ }
+
+ path.insert([r, c])
+ let res = dfs(r + 1, c, i + 1) ||
+ dfs(r - 1, c, i + 1) ||
+ dfs(r, c + 1, i + 1) ||
+ dfs(r, c - 1, i + 1)
+ path.remove([r, c])
+ return res
+ }
+
+ for r in 0.. Bool {
+ let ROWS = board.count
+ let COLS = board[0].count
+ var visited = Array(repeating: Array(repeating: false, count: COLS), count: ROWS)
+ let wordArray = Array(word)
+
+ func dfs(_ r: Int, _ c: Int, _ i: Int) -> Bool {
+ if i == wordArray.count {
+ return true
+ }
+ if (r < 0 || c < 0 || r >= ROWS || c >= COLS ||
+ board[r][c] != wordArray[i] || visited[r][c]) {
+ return false
+ }
+
+ visited[r][c] = true
+ let res = dfs(r + 1, c, i + 1) ||
+ dfs(r - 1, c, i + 1) ||
+ dfs(r, c + 1, i + 1) ||
+ dfs(r, c - 1, i + 1)
+ visited[r][c] = false
+ return res
+ }
+
+ for r in 0.. Bool {
+ let ROWS = board.count
+ let COLS = board[0].count
+ let wordArray = Array(word)
+ var board = board
+
+ func dfs(_ r: Int, _ c: Int, _ i: Int) -> Bool {
+ if i == wordArray.count {
+ return true
+ }
+ if (r < 0 || c < 0 || r >= ROWS || c >= COLS ||
+ board[r][c] != wordArray[i] || board[r][c] == "#") {
+ return false
+ }
+
+ let temp = board[r][c]
+ board[r][c] = "#"
+ let res = dfs(r + 1, c, i + 1) ||
+ dfs(r - 1, c, i + 1) ||
+ dfs(r, c + 1, i + 1) ||
+ dfs(r, c - 1, i + 1)
+ board[r][c] = temp
+ return res
+ }
+
+ for r in 0.. String {
+ var res = [String]()
+
+ func dfs(_ node: TreeNode?) {
+ guard let node = node else {
+ res.append("N")
+ return
+ }
+ res.append("\(node.val)")
+ dfs(node.left)
+ dfs(node.right)
+ }
+
+ dfs(root)
+ return res.joined(separator: ",")
+ }
+
+ func deserialize(_ data: String) -> TreeNode? {
+ var vals = data.split(separator: ",").map { String($0) }
+ var i = 0
+
+ func dfs() -> TreeNode? {
+ if vals[i] == "N" {
+ i += 1
+ return nil
+ }
+ let node = TreeNode(Int(vals[i])!)
+ i += 1
+ node.left = dfs()
+ node.right = dfs()
+ return node
+ }
+
+ return dfs()
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
@@ -863,6 +918,76 @@ class Codec {
}
```
+```swift
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public var val: Int
+ * public var left: TreeNode?
+ * public var right: TreeNode?
+ * public init(_ val: Int) {
+ * self.val = val
+ * self.left = nil
+ * self.right = nil
+ * }
+ * }
+ */
+
+class Codec {
+
+ func serialize(_ root: TreeNode?) -> String {
+ guard let root = root else {
+ return "N"
+ }
+
+ var res = [String]()
+ var queue: Deque = [root]
+
+ while !queue.isEmpty {
+ let node = queue.removeFirst()
+ if let node = node {
+ res.append("\(node.val)")
+ queue.append(node.left)
+ queue.append(node.right)
+ } else {
+ res.append("N")
+ }
+ }
+
+ return res.joined(separator: ",")
+ }
+
+ func deserialize(_ data: String) -> TreeNode? {
+ let vals = data.split(separator: ",").map { String($0) }
+ guard vals[0] != "N" else {
+ return nil
+ }
+
+ let root = TreeNode(Int(vals[0])!)
+ var queue: Deque = [root]
+ var index = 1
+
+ while !queue.isEmpty {
+ let node = queue.popFirst()!
+
+ if vals[index] != "N" {
+ node.left = TreeNode(Int(vals[index])!)
+ queue.append(node.left!)
+ }
+ index += 1
+
+ if vals[index] != "N" {
+ node.right = TreeNode(Int(vals[index])!)
+ queue.append(node.right!)
+ }
+ index += 1
+ }
+
+ return root
+ }
+}
+```
+
::tabs-end
### Time & Space Complexity
diff --git a/articles/set-zeroes-in-matrix.md b/articles/set-zeroes-in-matrix.md
index 5a265e1f5..72cef4283 100644
--- a/articles/set-zeroes-in-matrix.md
+++ b/articles/set-zeroes-in-matrix.md
@@ -208,6 +208,35 @@ class Solution {
}
```
+```swift
+class Solution {
+ func setZeroes(_ matrix: inout [[Int]]) {
+ let rows = matrix.count
+ let cols = matrix[0].count
+ var mark = matrix
+
+ for r in 0.. 0 {
+ matrix[r][0] = 0
+ } else {
+ rowZero = true
+ }
+ }
+ }
+ }
+
+ for r in 1.. Int {
+ for i in 0.. Int {
+ var seen = Set