diff --git a/README.md b/README.md
index c338b6ace..621435471 100644
--- a/README.md
+++ b/README.md
@@ -166,7 +166,7 @@ If you would like to have collaborator permissions on the repo to merge your own
[0441 - Arranging Coins](https://leetcode.com/problems/arranging-coins/) | ❌
| ❌
| [✔️](cpp%2F0441-arranging-coins.cpp)
| ❌
| ❌
| ❌
| ❌
| [✔️](java%2F0441-arranging-coins.java)
| [✔️](javascript%2F0441-arranging-coins.js)
| [✔️](kotlin%2F0441-arranging-coins.kt)
| [✔️](python%2F0441-arranging-coins.py)
| ❌
| [✔️](rust%2F0441-arranging-coins.rs)
| ❌
| ❌
| ❌
[0977 - Squares of a Sorted Array](https://leetcode.com/problems/squares-of-a-sorted-array/) | ❌
| ❌
| [✔️](cpp%2F0977-squares-of-a-sorted-array.cpp)
| ❌
| ❌
| [✔️](go%2F0977-squares-of-a-sorted-array.go)
| ❌
| [✔️](java%2F0977-squares-of-a-sorted-array.java)
| [✔️](javascript%2F0977-squares-of-a-sorted-array.js)
| [✔️](kotlin%2F0977-squares-of-a-sorted-array.kt)
| [✔️](python%2F0977-squares-of-a-sorted-array.py)
| ❌
| [✔️](rust%2F0977-squares-of-a-sorted-array.rs)
| ❌
| [✔️](swift%2F0977-squares-of-a-sorted-array.swift)
| [✔️](typescript%2F0977-squares-of-a-sorted-array.ts)
[0367 - Valid Perfect Square](https://leetcode.com/problems/valid-perfect-square/) | ❌
| [✔️](c%2F0367-valid-perfect-square.c)
| [✔️](cpp%2F0367-valid-perfect-square.cpp)
| ❌
| ❌
| [✔️](go%2F0367-valid-perfect-square.go)
| ❌
| [✔️](java%2F0367-valid-perfect-square.java)
| [✔️](javascript%2F0367-valid-perfect-square.js)
| [✔️](kotlin%2F0367-valid-perfect-square.kt)
| [✔️](python%2F0367-valid-perfect-square.py)
| ❌
| ❌
| ❌
| [✔️](swift%2F0367-valid-perfect-square.swift)
| ❌
-[0069 - Sqrt(x) ](https://leetcode.com/problems/sqrtx/) | ❌
| [✔️](c%2F0069-sqrtx.c)
| [✔️](cpp%2F0069-sqrtx.cpp)
| ❌
| ❌
| ❌
| ❌
| [✔️](java%2F0069-sqrtx.java)
| [✔️](javascript%2F0069-sqrtx.js)
| [✔️](kotlin%2F0069-sqrtx.kt)
| [✔️](python%2F0069-sqrtx.py)
| ❌
| ❌
| ❌
| ❌
| ❌
+[0069 - Sqrt(x) ](https://leetcode.com/problems/sqrtx/) | ❌
| [✔️](c%2F0069-sqrtx.c)
| [✔️](cpp%2F0069-sqrtx.cpp)
| [✔️](csharp%2F0069-sqrtx.cs)
| ❌
| ❌
| ❌
| [✔️](java%2F0069-sqrtx.java)
| [✔️](javascript%2F0069-sqrtx.js)
| [✔️](kotlin%2F0069-sqrtx.kt)
| [✔️](python%2F0069-sqrtx.py)
| ❌
| ❌
| ❌
| ❌
| ❌
[0540 - Single Element in a Sorted Array](https://leetcode.com/problems/single-element-in-a-sorted-array/) | ❌
| [✔️](c%2F0540-single-element-in-a-sorted-array.c)
| [✔️](cpp%2F0540-single-element-in-a-sorted-array.cpp)
| ❌
| ❌
| ❌
| ❌
| [✔️](java%2F0540-single-element-in-a-sorted-array.java)
| [✔️](javascript%2F0540-single-element-in-a-sorted-array.js)
| [✔️](kotlin%2F0540-single-element-in-a-sorted-array.kt)
| [✔️](python%2F0540-single-element-in-a-sorted-array.py)
| ❌
| ❌
| ❌
| ❌
| [✔️](typescript%2F0540-single-element-in-a-sorted-array.ts)
[1011 - Capacity to Ship Packages](https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/) | ❌
| ❌
| [✔️](cpp%2F1011-capacity-to-ship-packages-within-d-days.cpp)
| ❌
| ❌
| ❌
| ❌
| [✔️](java%2F1011-capacity-to-ship-packages-within-d-days.java)
| ❌
| [✔️](kotlin%2F1011-capacity-to-ship-packages-within-d-days.kt)
| [✔️](python%2F1011-capacity-to-ship-packages-within-d-days.py)
| ❌
| ❌
| ❌
| ❌
| ❌
[0162 - Find Peak Element](https://leetcode.com/problems/find-peak-element/) | ❌
| [✔️](c%2F0162-find-peak-element.c)
| [✔️](cpp%2F0162-find-peak-element.cpp)
| ❌
| ❌
| ❌
| ❌
| [✔️](java%2F0162-find-peak-element.java)
| [✔️](javascript%2F0162-find-peak-element.js)
| [✔️](kotlin%2F0162-find-peak-element.kt)
| [✔️](python%2F0162-find-peak-element.py)
| ❌
| ❌
| ❌
| ❌
| ❌
@@ -192,7 +192,7 @@ If you would like to have collaborator permissions on the repo to merge your own
[0206 - Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/) | ❌
| [✔️](c%2F0206-reverse-linked-list.c)
| [✔️](cpp%2F0206-reverse-linked-list.cpp)
| [✔️](csharp%2F0206-reverse-linked-list.cs)
| [✔️](dart%2F0206-reverse-linked-list.dart)
| [✔️](go%2F0206-reverse-linked-list.go)
| ❌
| [✔️](java%2F0206-reverse-linked-list.java)
| [✔️](javascript%2F0206-reverse-linked-list.js)
| [✔️](kotlin%2F0206-reverse-linked-list.kt)
| [✔️](python%2F0206-reverse-linked-list.py)
| [✔️](ruby%2F0206-reverse-linked-list.rb)
| [✔️](rust%2F0206-reverse-linked-list.rs)
| [✔️](scala%2F0206-reverse-linked-list.scala)
| [✔️](swift%2F0206-reverse-linked-list.swift)
| [✔️](typescript%2F0206-reverse-linked-list.ts)
[0021 - Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/) | ❌
| [✔️](c%2F0021-merge-two-sorted-lists.c)
| [✔️](cpp%2F0021-merge-two-sorted-lists.cpp)
| [✔️](csharp%2F0021-merge-two-sorted-lists.cs)
| [✔️](dart%2F0021-merge-two-sorted-lists.dart)
| [✔️](go%2F0021-merge-two-sorted-lists.go)
| ❌
| [✔️](java%2F0021-merge-two-sorted-lists.java)
| [✔️](javascript%2F0021-merge-two-sorted-lists.js)
| [✔️](kotlin%2F0021-merge-two-sorted-lists.kt)
| [✔️](python%2F0021-merge-two-sorted-lists.py)
| [✔️](ruby%2F0021-merge-two-sorted-lists.rb)
| [✔️](rust%2F0021-merge-two-sorted-lists.rs)
| [✔️](scala%2F0021-merge-two-sorted-lists.scala)
| [✔️](swift%2F0021-merge-two-sorted-lists.swift)
| [✔️](typescript%2F0021-merge-two-sorted-lists.ts)
[0234 - Palindrome Linked List](https://leetcode.com/problems/palindrome-linked-list/) | ❌
| [✔️](c%2F0234-palindrome-linked-list.c)
| [✔️](cpp%2F0234-palindrome-linked-list.cpp)
| ❌
| ❌
| [✔️](go%2F0234-palindrome-linked-list.go)
| ❌
| [✔️](java%2F0234-palindrome-linked-list.java)
| [✔️](javascript%2F0234-palindrome-linked-list.js)
| [✔️](kotlin%2F0234-palindrome-linked-list.kt)
| [✔️](python%2F0234-palindrome-linked-list.py)
| ❌
| ❌
| ❌
| ❌
| ❌
-[0203 - Remove Linked List Elements](https://leetcode.com/problems/remove-linked-list-elements/) | ❌
| ❌
| [✔️](cpp%2F0203-remove-linked-list-elements.cpp)
| ❌
| ❌
| [✔️](go%2F0203-remove-linked-list-elements.go)
| ❌
| [✔️](java%2F0203-remove-linked-list-elements.java)
| [✔️](javascript%2F0203-remove-linked-list-elements.js)
| [✔️](kotlin%2F0203-remove-linked-list-elements.kt)
| [✔️](python%2F0203-remove-linked-list-elements.py)
| ❌
| ❌
| ❌
| ❌
| [✔️](typescript%2F0203-remove-linked-list-elements.ts)
+[0203 - Remove Linked List Elements](https://leetcode.com/problems/remove-linked-list-elements/) | ❌
| ❌
| [✔️](cpp%2F0203-remove-linked-list-elements.cpp)
| [✔️](csharp%2F0203-remove-linked-list-elements.cs)
| ❌
| [✔️](go%2F0203-remove-linked-list-elements.go)
| ❌
| [✔️](java%2F0203-remove-linked-list-elements.java)
| [✔️](javascript%2F0203-remove-linked-list-elements.js)
| [✔️](kotlin%2F0203-remove-linked-list-elements.kt)
| [✔️](python%2F0203-remove-linked-list-elements.py)
| ❌
| ❌
| ❌
| ❌
| [✔️](typescript%2F0203-remove-linked-list-elements.ts)
[0083 - Remove Duplicates From Sorted List](https://leetcode.com/problems/remove-duplicates-from-sorted-list/) | ❌
| [✔️](c%2F0083-remove-duplicates-from-sorted-list.c)
| [✔️](cpp%2F0083-remove-duplicates-from-sorted-list.cpp)
| ❌
| ❌
| [✔️](go%2F0083-remove-duplicates-from-sorted-list.go)
| ❌
| [✔️](java%2F0083-remove-duplicates-from-sorted-list.java)
| [✔️](javascript%2F0083-remove-duplicates-from-sorted-list.js)
| [✔️](kotlin%2F0083-remove-duplicates-from-sorted-list.kt)
| [✔️](python%2F0083-remove-duplicates-from-sorted-list.py)
| ❌
| ❌
| ❌
| [✔️](swift%2F0083-remove-duplicates-from-sorted-list.swift)
| ❌
[0876 - Middle of the Linked List](https://leetcode.com/problems/middle-of-the-linked-list/) | ❌
| [✔️](c%2F0876-middle-of-the-linked-list.c)
| [✔️](cpp%2F0876-middle-of-the-linked-list.cpp)
| [✔️](csharp%2F0876-middle-of-the-linked-list.cs)
| ❌
| [✔️](go%2F0876-middle-of-the-linked-list.go)
| ❌
| [✔️](java%2F0876-middle-of-the-linked-list.java)
| [✔️](javascript%2F0876-middle-of-the-linked-list.js)
| [✔️](kotlin%2F0876-middle-of-the-linked-list.kt)
| [✔️](python%2F0876-middle-of-the-linked-list.py)
| ❌
| [✔️](rust%2F0876-middle-of-the-linked-list.rs)
| ❌
| [✔️](swift%2F0876-middle-of-the-linked-list.swift)
| [✔️](typescript%2F0876-middle-of-the-linked-list.ts)
[0160 - Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/) | ❌
| [✔️](c%2F0160-intersection-of-two-linked-lists.c)
| [✔️](cpp%2F0160-intersection-of-two-linked-lists.cpp)
| ❌
| ❌
| [✔️](go%2F0160-intersection-of-two-linked-lists.go)
| ❌
| [✔️](java%2F0160-intersection-of-two-linked-lists.java)
| [✔️](javascript%2F0160-intersection-of-two-linked-lists.js)
| [✔️](kotlin%2F0160-intersection-of-two-linked-lists.kt)
| [✔️](python%2F0160-intersection-of-two-linked-lists.py)
| ❌
| ❌
| ❌
| ❌
| ❌
@@ -504,7 +504,7 @@ If you would like to have collaborator permissions on the repo to merge your own
[0048 - Rotate Image](https://leetcode.com/problems/rotate-image/) | ❌
| [✔️](c%2F0048-rotate-image.c)
| [✔️](cpp%2F0048-rotate-image.cpp)
| [✔️](csharp%2F0048-rotate-image.cs)
| ❌
| [✔️](go%2F0048-rotate-image.go)
| ❌
| [✔️](java%2F0048-rotate-image.java)
| [✔️](javascript%2F0048-rotate-image.js)
| [✔️](kotlin%2F0048-rotate-image.kt)
| [✔️](python%2F0048-rotate-image.py)
| [✔️](ruby%2F0048-rotate-image.rb)
| [✔️](rust%2F0048-rotate-image.rs)
| ❌
| [✔️](swift%2F0048-rotate-image.swift)
| [✔️](typescript%2F0048-rotate-image.ts)
[0054 - Spiral Matrix](https://leetcode.com/problems/spiral-matrix/) | ❌
| [✔️](c%2F0054-spiral-matrix.c)
| [✔️](cpp%2F0054-spiral-matrix.cpp)
| [✔️](csharp%2F0054-spiral-matrix.cs)
| ❌
| [✔️](go%2F0054-spiral-matrix.go)
| ❌
| [✔️](java%2F0054-spiral-matrix.java)
| [✔️](javascript%2F0054-spiral-matrix.js)
| [✔️](kotlin%2F0054-spiral-matrix.kt)
| [✔️](python%2F0054-spiral-matrix.py)
| [✔️](ruby%2F0054-spiral-matrix.rb)
| ❌
| ❌
| [✔️](swift%2F0054-spiral-matrix.swift)
| [✔️](typescript%2F0054-spiral-matrix.ts)
[0059 - Spiral Matrix II ](https://leetcode.com/problems/spiral-matrix-ii/) | ❌
| ❌
| [✔️](cpp%2F0059-spiral-matrix-ii.cpp)
| ❌
| ❌
| ❌
| ❌
| [✔️](java%2F0059-spiral-matrix-ii.java)
| [✔️](javascript%2F0059-spiral-matrix-ii.js)
| [✔️](kotlin%2F0059-spiral-matrix-ii.kt)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
-[0073 - Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/) | ❌
| [✔️](c%2F0073-set-matrix-zeroes.c)
| [✔️](cpp%2F0073-set-matrix-zeroes.cpp)
| [✔️](csharp%2F0073-set-matrix-zeroes.cs)
| ❌
| [✔️](go%2F0073-set-matrix-zeroes.go)
| ❌
| [✔️](java%2F0073-set-matrix-zeroes.java)
| [✔️](javascript%2F0073-set-matrix-zeroes.js)
| [✔️](kotlin%2F0073-set-matrix-zeroes.kt)
| [✔️](python%2F0073-set-matrix-zeroes.py)
| [✔️](ruby%2F0073-set-matrix-zeroes.rb)
| ❌
| ❌
| ❌
| [✔️](typescript%2F0073-set-matrix-zeroes.ts)
+[0073 - Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/) | ❌
| [✔️](c%2F0073-set-matrix-zeroes.c)
| [✔️](cpp%2F0073-set-matrix-zeroes.cpp)
| [✔️](csharp%2F0073-set-matrix-zeroes.cs)
| ❌
| [✔️](go%2F0073-set-matrix-zeroes.go)
| ❌
| [✔️](java%2F0073-set-matrix-zeroes.java)
| [✔️](javascript%2F0073-set-matrix-zeroes.js)
| [✔️](kotlin%2F0073-set-matrix-zeroes.kt)
| [✔️](python%2F0073-set-matrix-zeroes.py)
| [✔️](ruby%2F0073-set-matrix-zeroes.rb)
| ❌
| ❌
| [✔️](swift%2F0073-set-matrix-zeroes.swift)
| [✔️](typescript%2F0073-set-matrix-zeroes.ts)
[0202 - Happy Number](https://leetcode.com/problems/happy-number/) | ❌
| [✔️](c%2F0202-happy-number.c)
| [✔️](cpp%2F0202-happy-number.cpp)
| [✔️](csharp%2F0202-happy-number.cs)
| ❌
| [✔️](go%2F0202-happy-number.go)
| ❌
| [✔️](java%2F0202-happy-number.java)
| [✔️](javascript%2F0202-happy-number.js)
| [✔️](kotlin%2F0202-happy-number.kt)
| [✔️](python%2F0202-happy-number.py)
| [✔️](ruby%2F0202-happy-number.rb)
| [✔️](rust%2F0202-happy-number.rs)
| ❌
| [✔️](swift%2F0202-happy-number.swift)
| [✔️](typescript%2F0202-happy-number.ts)
[0066 - Plus One](https://leetcode.com/problems/plus-one/) | ❌
| [✔️](c%2F0066-plus-one.c)
| [✔️](cpp%2F0066-plus-one.cpp)
| [✔️](csharp%2F0066-plus-one.cs)
| ❌
| [✔️](go%2F0066-plus-one.go)
| ❌
| [✔️](java%2F0066-plus-one.java)
| [✔️](javascript%2F0066-plus-one.js)
| [✔️](kotlin%2F0066-plus-one.kt)
| [✔️](python%2F0066-plus-one.py)
| [✔️](ruby%2F0066-plus-one.rb)
| [✔️](rust%2F0066-plus-one.rs)
| ❌
| [✔️](swift%2F0066-plus-one.swift)
| [✔️](typescript%2F0066-plus-one.ts)
[0009 - Palindrome Number](https://leetcode.com/problems/palindrome-number/) | ❌
| [✔️](c%2F0009-palindrome-number.c)
| [✔️](cpp%2F0009-palindrome-number.cpp)
| ❌
| ❌
| [✔️](go%2F0009-palindrome-number.go)
| ❌
| [✔️](java%2F0009-palindrome-number.java)
| [✔️](javascript%2F0009-palindrome-number.js)
| [✔️](kotlin%2F0009-palindrome-number.kt)
| [✔️](python%2F0009-palindrome-number.py)
| ❌
| [✔️](rust%2F0009-palindrome-number.rs)
| ❌
| [✔️](swift%2F0009-palindrome-number.swift)
| [✔️](typescript%2F0009-palindrome-number.ts)
@@ -514,7 +514,7 @@ If you would like to have collaborator permissions on the repo to merge your own
[0012 - Integer to Roman](https://leetcode.com/problems/integer-to-roman/) | ❌
| ❌
| [✔️](cpp%2F0012-integer-to-roman.cpp)
| ❌
| ❌
| [✔️](go%2F0012-integer-to-roman.go)
| ❌
| [✔️](java%2F0012-integer-to-roman.java)
| [✔️](javascript%2F0012-integer-to-roman.js)
| [✔️](kotlin%2F0012-integer-to-roman.kt)
| [✔️](python%2F0012-integer-to-roman.py)
| ❌
| [✔️](rust%2F0012-integer-to-roman.rs)
| ❌
| ❌
| [✔️](typescript%2F0012-integer-to-roman.ts)
[0050 - Pow(x, n)](https://leetcode.com/problems/powx-n/) | ❌
| [✔️](c%2F0050-powx-n.c)
| [✔️](cpp%2F0050-powx-n.cpp)
| [✔️](csharp%2F0050-powx-n.cs)
| ❌
| ❌
| ❌
| [✔️](java%2F0050-powx-n.java)
| [✔️](javascript%2F0050-powx-n.js)
| [✔️](kotlin%2F0050-powx-n.kt)
| [✔️](python%2F0050-powx-n.py)
| [✔️](ruby%2F0050-powx-n.rb)
| [✔️](rust%2F0050-powx-n.rs)
| ❌
| [✔️](swift%2F0050-powx-n.swift)
| [✔️](typescript%2F0050-powx-n.ts)
[0043 - Multiply Strings](https://leetcode.com/problems/multiply-strings/) | ❌
| [✔️](c%2F0043-multiply-strings.c)
| [✔️](cpp%2F0043-multiply-strings.cpp)
| [✔️](csharp%2F0043-multiply-strings.cs)
| ❌
| ❌
| ❌
| [✔️](java%2F0043-multiply-strings.java)
| [✔️](javascript%2F0043-multiply-strings.js)
| [✔️](kotlin%2F0043-multiply-strings.kt)
| [✔️](python%2F0043-multiply-strings.py)
| [✔️](ruby%2F0043-multiply-strings.rb)
| [✔️](rust%2F0043-multiply-strings.rs)
| ❌
| [✔️](swift%2F0043-multiply-strings.swift)
| [✔️](typescript%2F0043-multiply-strings.ts)
-[2013 - Detect Squares](https://leetcode.com/problems/detect-squares/) | ❌
| ❌
| [✔️](cpp%2F2013-Detect-Squares.cpp)
| [✔️](csharp%2F2013-Detect-Squares.cs)
| ❌
| ❌
| ❌
| [✔️](java%2F2013-Detect-Squares.java)
| [✔️](javascript%2F2013-Detect-Squares.js)
| [✔️](kotlin%2F2013-detect-squares.kt)
| [✔️](python%2F2013-detect-squares.py)
| [✔️](ruby%2F2013-detect-squares.rb)
| [✔️](rust%2F2013-detect-squares.rs)
| ❌
| ❌
| ❌
+[2013 - Detect Squares](https://leetcode.com/problems/detect-squares/) | ❌
| ❌
| [✔️](cpp%2F2013-Detect-Squares.cpp)
| [✔️](csharp%2F2013-Detect-Squares.cs)
| ❌
| ❌
| ❌
| [✔️](java%2F2013-Detect-Squares.java)
| [✔️](javascript%2F2013-Detect-Squares.js)
| [✔️](kotlin%2F2013-detect-squares.kt)
| [✔️](python%2F2013-detect-squares.py)
| [✔️](ruby%2F2013-detect-squares.rb)
| [✔️](rust%2F2013-detect-squares.rs)
| ❌
| [✔️](swift%2F2013-detect-squares.swift)
| ❌
[1041 - Robot Bounded In Circle](https://leetcode.com/problems/robot-bounded-in-circle/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](java%2F1041-robot-bounded-in-circle.java)
| ❌
| [✔️](kotlin%2F1041-robot-bounded-in-circle.kt)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
[0006 - Zigzag Conversion](https://leetcode.com/problems/zigzag-conversion/) | ❌
| ❌
| [✔️](cpp%2F0006-zigzag-conversion.cpp)
| ❌
| ❌
| [✔️](go%2F0006-zigzag-conversion.go)
| ❌
| [✔️](java%2F0006-zigzag-conversion.java)
| ❌
| [✔️](kotlin%2F0006-zigzag-conversion.kt)
| [✔️](python%2F0006-zigzag-conversion.py)
| ❌
| ❌
| ❌
| ❌
| ❌
[2028 - Find Missing Observations](https://leetcode.com/problems/find-missing-observations/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](kotlin%2F2028-find-missing-observations.kt)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
@@ -542,17 +542,17 @@ If you would like to have collaborator permissions on the repo to merge your own
[2620 - Counter](https://leetcode.com/problems/counter/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](javascript%2F2620-counter.js)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](typescript%2F2620-counter.ts)
[2665 - Counter II](https://leetcode.com/problems/counter-ii/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](javascript%2F2665-counter-ii.js)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
[2635 - Apply Transform over each Element in Array](https://leetcode.com/problems/apply-transform-over-each-element-in-array/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](javascript%2F2635-apply-transform-over-each-element-in-array.js)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
-[2634 - Filter Elements from Array](https://leetcode.com/problems/filter-elements-from-array/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
-[2626 - Array Reduce Transformation](https://leetcode.com/problems/array-reduce-transformation/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
-[2629 - Function Composition](https://leetcode.com/problems/function-composition/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
-[2666 - Allow One Function Call](https://leetcode.com/problems/allow-one-function-call/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
-[2623 - Memoize](https://leetcode.com/problems/memoize/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
-[2632 - Curry](https://leetcode.com/problems/curry/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
-[2621 - Sleep](https://leetcode.com/problems/sleep/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
+[2634 - Filter Elements from Array](https://leetcode.com/problems/filter-elements-from-array/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](javascript%2F2634-filter-elements-from-array.js)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
+[2626 - Array Reduce Transformation](https://leetcode.com/problems/array-reduce-transformation/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](javascript%2F2626-array-reduce-transformation.js)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
+[2629 - Function Composition](https://leetcode.com/problems/function-composition/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](javascript%2F2629-function-composition.js)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
+[2666 - Allow One Function Call](https://leetcode.com/problems/allow-one-function-call/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](javascript%2F2666-allow-one-function-call.js)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
+[2623 - Memoize](https://leetcode.com/problems/memoize/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](javascript%2F2623-memoize.js)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
+[2632 - Curry](https://leetcode.com/problems/curry/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](javascript%2F2632-curry.js)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
+[2621 - Sleep](https://leetcode.com/problems/sleep/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](javascript%2F2621-sleep.js)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
[2637 - Promise Time Limit](https://leetcode.com/problems/promise-time-limit/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
[2636 - Promise Pool](https://leetcode.com/problems/promise-pool/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
[2622 - Cache With Time Limit](https://leetcode.com/problems/cache-with-time-limit/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
-[2627 - Debounce](https://leetcode.com/problems/debounce/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
+[2627 - Debounce](https://leetcode.com/problems/debounce/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](javascript%2F2627-debounce.js)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
[2676 - Throttle](https://leetcode.com/problems/throttle/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
[2628 - JSON Deep Equal](https://leetcode.com/problems/json-deep-equal/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| [✔️](javascript%2F2628-json-deep-equal.js)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
[2633 - Convert Object to JSON String](https://leetcode.com/problems/convert-object-to-json-string/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
diff --git a/articles/132-pattern.md b/articles/132-pattern.md
new file mode 100644
index 000000000..b0dc31957
--- /dev/null
+++ b/articles/132-pattern.md
@@ -0,0 +1,420 @@
+## 1. Brute Force
+
+::tabs-start
+
+```python
+class Solution:
+ def find132pattern(self, nums: List[int]) -> bool:
+ n = len(nums)
+
+ for k in range(2, n):
+ for j in range(k - 1, 0, -1):
+ if nums[j] <= nums[k]:
+ continue
+
+ for i in range(j - 1, -1, -1):
+ if nums[i] < nums[k]:
+ return True
+
+ return False
+```
+
+```java
+public class Solution {
+ public boolean find132pattern(int[] nums) {
+ int n = nums.length;
+
+ for (int k = 2; k < n; k++) {
+ for (int j = k - 1; j > 0; j--) {
+ if (nums[j] <= nums[k]) {
+ continue;
+ }
+
+ for (int i = j - 1; i >= 0; i--) {
+ if (nums[i] < nums[k]) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ bool find132pattern(vector& nums) {
+ int n = nums.size();
+
+ for (int k = 2; k < n; k++) {
+ for (int j = k - 1; j > 0; j--) {
+ if (nums[j] <= nums[k]) {
+ continue;
+ }
+
+ for (int i = j - 1; i >= 0; i--) {
+ if (nums[i] < nums[k]) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} nums
+ * @return {boolean}
+ */
+ find132pattern(nums) {
+ let n = nums.length;
+
+ for (let k = 2; k < n; k++) {
+ for (let j = k - 1; j > 0; j--) {
+ if (nums[j] <= nums[k]) {
+ continue;
+ }
+
+ for (let i = j - 1; i >= 0; i--) {
+ if (nums[i] < nums[k]) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n ^ 2)$
+* Space complexity: $O(1)$
+
+---
+
+## 2. Stack
+
+::tabs-start
+
+```python
+class Solution:
+ def find132pattern(self, nums: List[int]) -> bool:
+ stack = [] # pair [num, minLeft], mono decreasing
+ curMin = nums[0]
+
+ for i in range(1, len(nums)):
+ while stack and nums[i] >= stack[-1][0]:
+ stack.pop()
+ if stack and nums[i] > stack[-1][1]:
+ return True
+
+ stack.append([nums[i], curMin])
+ curMin = min(curMin, nums[i])
+
+ return False
+```
+
+```java
+public class Solution {
+ public boolean find132pattern(int[] nums) {
+ Stack stack = new Stack<>(); // pair [num, minLeft]
+ int curMin = nums[0];
+
+ for (int i = 1; i < nums.length; i++) {
+ while (!stack.isEmpty() && nums[i] >= stack.peek()[0]) {
+ stack.pop();
+ }
+ if (!stack.isEmpty() && nums[i] > stack.peek()[1]) {
+ return true;
+ }
+
+ stack.push(new int[]{nums[i], curMin});
+ curMin = Math.min(curMin, nums[i]);
+ }
+
+ return false;
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ bool find132pattern(vector& nums) {
+ stack> stack; // pair
+ int curMin = nums[0];
+
+ for (int i = 1; i < nums.size(); i++) {
+ while (!stack.empty() && nums[i] >= stack.top().first) {
+ stack.pop();
+ }
+ if (!stack.empty() && nums[i] > stack.top().second) {
+ return true;
+ }
+
+ stack.push({nums[i], curMin});
+ curMin = min(curMin, nums[i]);
+ }
+
+ return false;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} nums
+ * @return {boolean}
+ */
+ find132pattern(nums) {
+ const stack = []; // pair [num, minLeft]
+ let curMin = nums[0];
+
+ for (let i = 1; i < nums.length; i++) {
+ while (stack.length > 0 && nums[i] >= stack[stack.length - 1][0]) {
+ stack.pop();
+ }
+ if (stack.length > 0 && nums[i] > stack[stack.length - 1][1]) {
+ return true;
+ }
+
+ stack.push([nums[i], curMin]);
+ curMin = Math.min(curMin, nums[i]);
+ }
+
+ return false;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n)$
+* Space complexity: $O(n)$
+
+---
+
+## 3. Stack (Optimal)
+
+::tabs-start
+
+```python
+class Solution:
+ def find132pattern(self, nums: List[int]) -> bool:
+ stack, k = [], float('-inf')
+
+ for i in range(len(nums) - 1, -1, -1):
+ if nums[i] < k:
+ return True
+
+ while stack and stack[-1] < nums[i]:
+ k = stack.pop()
+ stack.append(nums[i])
+
+ return False
+```
+
+```java
+public class Solution {
+ public boolean find132pattern(int[] nums) {
+ Stack stack = new Stack<>();
+ int k = Integer.MIN_VALUE;
+
+ for (int i = nums.length - 1; i >= 0; i--) {
+ if (nums[i] < k) {
+ return true;
+ }
+
+ while (!stack.isEmpty() && stack.peek() < nums[i]) {
+ k = stack.pop();
+ }
+ stack.push(nums[i]);
+ }
+
+ return false;
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ bool find132pattern(vector& nums) {
+ stack stack;
+ int k = INT_MIN;
+
+ for (int i = nums.size() - 1; i >= 0; i--) {
+ if (nums[i] < k) {
+ return true;
+ }
+
+ while (!stack.empty() && stack.top() < nums[i]) {
+ k = stack.top();
+ stack.pop();
+ }
+ stack.push(nums[i]);
+ }
+
+ return false;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} nums
+ * @return {boolean}
+ */
+ find132pattern(nums) {
+ const stack = [];
+ let k = -Infinity;
+
+ for (let i = nums.length - 1; i >= 0; i--) {
+ if (nums[i] < k) {
+ return true;
+ }
+
+ while (stack.length > 0 && stack[stack.length - 1] < nums[i]) {
+ k = stack.pop();
+ }
+ stack.push(nums[i]);
+ }
+
+ return false;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n)$
+* Space complexity: $O(n)$
+
+---
+
+## 4. Two Pointers
+
+::tabs-start
+
+```python
+class Solution:
+ def find132pattern(self, nums: List[int]) -> bool:
+ n = len(nums)
+ stkTop, k = n, float('-inf')
+
+ for i in range(n - 1, -1, -1):
+ if nums[i] < k:
+ return True
+
+ while stkTop < n and nums[i] > nums[stkTop]:
+ k = nums[stkTop]
+ stkTop += 1
+
+ stkTop -= 1
+ nums[stkTop] = nums[i]
+
+ return False
+```
+
+```java
+public class Solution {
+ public boolean find132pattern(int[] nums) {
+ int n = nums.length;
+ int stkTop = n;
+ int k = Integer.MIN_VALUE;
+
+ for (int i = n - 1; i >= 0; i--) {
+ if (nums[i] < k) {
+ return true;
+ }
+
+ while (stkTop < n && nums[i] > nums[stkTop]) {
+ k = nums[stkTop++];
+ }
+
+ nums[--stkTop] = nums[i];
+ }
+
+ return false;
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ bool find132pattern(vector& nums) {
+ int n = nums.size();
+ int stkTop = n;
+ int k = INT_MIN;
+
+ for (int i = n - 1; i >= 0; i--) {
+ if (nums[i] < k) {
+ return true;
+ }
+
+ while (stkTop < n && nums[i] > nums[stkTop]) {
+ k = nums[stkTop++];
+ }
+
+ nums[--stkTop] = nums[i];
+ }
+
+ return false;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} nums
+ * @return {boolean}
+ */
+ find132pattern(nums) {
+ const n = nums.length;
+ let stkTop = n;
+ let k = -Infinity;
+
+ for (let i = n - 1; i >= 0; i--) {
+ if (nums[i] < k) {
+ return true;
+ }
+
+ while (stkTop < n && nums[i] > nums[stkTop]) {
+ k = nums[stkTop++];
+ }
+
+ nums[--stkTop] = nums[i];
+ }
+
+ return false;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n)$
+* Space complexity: $O(1)$ extra space.
\ No newline at end of file
diff --git a/articles/4sum.md b/articles/4sum.md
new file mode 100644
index 000000000..b590cf39e
--- /dev/null
+++ b/articles/4sum.md
@@ -0,0 +1,810 @@
+## 1. Brute Force
+
+::tabs-start
+
+```python
+class Solution:
+ def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
+ n = len(nums)
+ nums.sort()
+ res = set()
+
+ for a in range(n):
+ for b in range(a + 1, n):
+ for c in range(b + 1, n):
+ for d in range(c + 1, n):
+ if nums[a] + nums[b] + nums[c] + nums[d] == target:
+ res.add((nums[a], nums[b], nums[c], nums[d]))
+ return list(res)
+```
+
+```java
+public class Solution {
+ public List> fourSum(int[] nums, int target) {
+ int n = nums.length;
+ Arrays.sort(nums);
+ Set> res = new HashSet<>();
+
+ for (int a = 0; a < n; a++) {
+ for (int b = a + 1; b < n; b++) {
+ for (int c = b + 1; c < n; c++) {
+ for (int d = c + 1; d < n; d++) {
+ if (nums[a] + nums[b] + 0L + nums[c] + nums[d] == target) {
+ res.add(Arrays.asList(nums[a], nums[b], nums[c], nums[d]));
+ }
+ }
+ }
+ }
+ }
+
+ return new ArrayList<>(res);
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ vector> fourSum(vector& nums, int target) {
+ int n = nums.size();
+ sort(nums.begin(), nums.end());
+ set> res;
+
+ for (int a = 0; a < n; a++) {
+ for (int b = a + 1; b < n; b++) {
+ for (int c = b + 1; c < n; c++) {
+ for (int d = c + 1; d < n; d++) {
+ if (nums[a] + nums[b] + 0LL + nums[c] + nums[d] == target) {
+ res.insert({nums[a], nums[b], nums[c], nums[d]});
+ }
+ }
+ }
+ }
+ }
+
+ return vector>(res.begin(), res.end());
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} nums
+ * @param {number} target
+ * @return {number[][]}
+ */
+ fourSum(nums, target) {
+ let n = nums.length;
+ nums.sort((a, b) => a - b);
+ let res = new Set();
+
+ for (let a = 0; a < n; a++) {
+ for (let b = a + 1; b < n; b++) {
+ for (let c = b + 1; c < n; c++) {
+ for (let d = c + 1; d < n; d++) {
+ if (nums[a] + nums[b] + nums[c] + nums[d] === target) {
+ res.add(JSON.stringify([nums[a], nums[b], nums[c], nums[d]]));
+ }
+ }
+ }
+ }
+ }
+
+ return Array.from(res).map(JSON.parse);
+ }
+}
+```
+
+```csharp
+public class Solution {
+ public List> FourSum(int[] nums, int target) {
+ int n = nums.Length;
+ Array.Sort(nums);
+ HashSet<(int, int, int, int)> res = new HashSet<(int, int, int, int)>();
+
+ for (int a = 0; a < n; a++) {
+ for (int b = a + 1; b < n; b++) {
+ for (int c = b + 1; c < n; c++) {
+ for (int d = c + 1; d < n; d++) {
+ long sum = (long)nums[a] + nums[b] + nums[c] + nums[d];
+ if (sum == target) {
+ res.Add((nums[a], nums[b], nums[c], nums[d]));
+ }
+ }
+ }
+ }
+ }
+
+ var result = new List>();
+ foreach (var quad in res) {
+ result.Add(new List { quad.Item1, quad.Item2, quad.Item3, quad.Item4 });
+ }
+ return result;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n ^ 4)$
+* Space complexity: $O(m)$
+
+> Where $n$ is the size of the array $nums$ and $m$ is the number of quadruplets.
+
+---
+
+## 2. Hash Map
+
+::tabs-start
+
+```python
+class Solution:
+ def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
+ nums.sort()
+ count = defaultdict(int)
+ for num in nums:
+ count[num] += 1
+
+ res = []
+ for i in range(len(nums)):
+ count[nums[i]] -= 1
+ if i > 0 and nums[i] == nums[i - 1]:
+ continue
+
+ for j in range(i + 1, len(nums)):
+ count[nums[j]] -= 1
+ if j > i + 1 and nums[j] == nums[j - 1]:
+ continue
+
+ for k in range(j + 1, len(nums)):
+ count[nums[k]] -= 1
+ if k > j + 1 and nums[k] == nums[k - 1]:
+ continue
+
+ fourth = target - (nums[i] + nums[j] + nums[k])
+ if count[fourth] > 0:
+ res.append([nums[i], nums[j], nums[k], fourth])
+
+ for k in range(j + 1, len(nums)):
+ count[nums[k]] += 1
+
+ for j in range(i + 1, len(nums)):
+ count[nums[j]] += 1
+
+ return res
+```
+
+```java
+public class Solution {
+ public List> fourSum(int[] nums, int target) {
+ Arrays.sort(nums);
+ Map count = new HashMap<>();
+ for (int num : nums) {
+ count.put(num, count.getOrDefault(num, 0) + 1);
+ }
+ List> res = new ArrayList<>();
+
+ for (int i = 0; i < nums.length; i++) {
+ count.put(nums[i], count.get(nums[i]) - 1);
+ if (i > 0 && nums[i] == nums[i - 1]) continue;
+
+ for (int j = i + 1; j < nums.length; j++) {
+ count.put(nums[j], count.get(nums[j]) - 1);
+ if (j > i + 1 && nums[j] == nums[j - 1]) continue;
+
+ for (int k = j + 1; k < nums.length; k++) {
+ count.put(nums[k], count.get(nums[k]) - 1);
+ if (k > j + 1 && nums[k] == nums[k - 1]) continue;
+
+ long fourth = target - (nums[i] + nums[j] + 0L + nums[k]);
+ if (fourth > Integer.MAX_VALUE || fourth < Integer.MIN_VALUE) {
+ continue;
+ }
+ if (count.getOrDefault((int) fourth, 0) > 0) {
+ res.add(Arrays.asList(nums[i], nums[j], nums[k], (int) fourth));
+ }
+ }
+
+ for (int k = j + 1; k < nums.length; k++) {
+ count.put(nums[k], count.get(nums[k]) + 1);
+ }
+ }
+
+ for (int j = i + 1; j < nums.length; j++) {
+ count.put(nums[j], count.get(nums[j]) + 1);
+ }
+ }
+
+ return res;
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ vector> fourSum(vector& nums, int target) {
+ sort(nums.begin(), nums.end());
+ unordered_map count;
+ for (int num : nums) {
+ count[num]++;
+ }
+ vector> res;
+
+ for (int i = 0; i < nums.size(); i++) {
+ count[nums[i]]--;
+ if (i > 0 && nums[i] == nums[i - 1]) continue;
+
+ for (int j = i + 1; j < nums.size(); j++) {
+ count[nums[j]]--;
+ if (j > i + 1 && nums[j] == nums[j - 1]) continue;
+
+ for (int k = j + 1; k < nums.size(); k++) {
+ count[nums[k]]--;
+ if (k > j + 1 && nums[k] == nums[k - 1]) continue;
+
+ long long fourth = target - (nums[i] + nums[j] + 0LL + nums[k]);
+ if (fourth < INT_MIN || fourth > INT_MAX) continue;
+ if (count[fourth] > 0) {
+ res.push_back({nums[i], nums[j], nums[k], int(fourth)});
+ }
+ }
+
+ for (int k = j + 1; k < nums.size(); k++) {
+ count[nums[k]]++;
+ }
+ }
+
+ for (int j = i + 1; j < nums.size(); j++) {
+ count[nums[j]]++;
+ }
+ }
+
+ return res;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} nums
+ * @param {number} target
+ * @return {number[][]}
+ */
+ fourSum(nums, target) {
+ nums.sort((a, b) => a - b);
+ const count = new Map();
+ for (const num of nums) {
+ count.set(num, (count.get(num) || 0) + 1);
+ }
+ const res = [];
+
+ for (let i = 0; i < nums.length; i++) {
+ count.set(nums[i], count.get(nums[i]) - 1);
+ if (i > 0 && nums[i] === nums[i - 1]) continue;
+
+ for (let j = i + 1; j < nums.length; j++) {
+ count.set(nums[j], count.get(nums[j]) - 1);
+ if (j > i + 1 && nums[j] === nums[j - 1]) continue;
+
+ for (let k = j + 1; k < nums.length; k++) {
+ count.set(nums[k], count.get(nums[k]) - 1);
+ if (k > j + 1 && nums[k] === nums[k - 1]) continue;
+
+ const fourth = target - (nums[i] + nums[j] + nums[k]);
+ if ((count.get(fourth) || 0) > 0) {
+ res.push([nums[i], nums[j], nums[k], fourth]);
+ }
+ }
+
+ for (let k = j + 1; k < nums.length; k++) {
+ count.set(nums[k], count.get(nums[k]) + 1);
+ }
+ }
+
+ for (let j = i + 1; j < nums.length; j++) {
+ count.set(nums[j], count.get(nums[j]) + 1);
+ }
+ }
+
+ return res;
+ }
+}
+```
+
+```csharp
+public class Solution {
+ public List> FourSum(int[] nums, int target) {
+ Array.Sort(nums);
+ Dictionary count = new Dictionary();
+
+ foreach (int num in nums) {
+ if (!count.ContainsKey(num)) {
+ count[num] = 0;
+ }
+ count[num]++;
+ }
+
+ List> res = new List>();
+
+ for (int i = 0; i < nums.Length; i++) {
+ count[nums[i]]--;
+ if (i > 0 && nums[i] == nums[i - 1]) continue;
+
+ for (int j = i + 1; j < nums.Length; j++) {
+ count[nums[j]]--;
+ if (j > i + 1 && nums[j] == nums[j - 1]) continue;
+
+ for (int k = j + 1; k < nums.Length; k++) {
+ count[nums[k]]--;
+ if (k > j + 1 && nums[k] == nums[k - 1]) continue;
+
+ long fourth = (long)target - (long)nums[i] - (long)nums[j] - (long)nums[k];
+ if (fourth > int.MaxValue || fourth < int.MinValue) {
+ continue;
+ }
+
+ if (count.ContainsKey((int)fourth) && count[(int)fourth] > 0) {
+ res.Add(new List { nums[i], nums[j], nums[k], (int)fourth });
+ }
+ }
+
+ for (int k = j + 1; k < nums.Length; k++) {
+ count[nums[k]]++;
+ }
+ }
+
+ for (int j = i + 1; j < nums.Length; j++) {
+ count[nums[j]]++;
+ }
+ }
+
+ return res;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n ^ 3)$
+* Space complexity:
+ * $O(n)$ space for the hash map.
+ * $O(m)$ space for the output array.
+
+> Where $n$ is the size of the array $nums$ and $m$ is the number of quadruplets.
+
+---
+
+## 3. Two Pointers
+
+::tabs-start
+
+```python
+class Solution:
+ def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
+ nums.sort()
+ n = len(nums)
+ res = []
+
+ for i in range(n):
+ if i > 0 and nums[i] == nums[i - 1]:
+ continue
+ for j in range(i + 1, n):
+ if j > i + 1 and nums[j] == nums[j - 1]:
+ continue
+ left, right = j + 1, n - 1
+ while left < right:
+ total = nums[i] + nums[j] + nums[left] + nums[right]
+ if total == target:
+ res.append([nums[i], nums[j], nums[left], nums[right]])
+ left += 1
+ right -= 1
+ while left < right and nums[left] == nums[left - 1]:
+ left += 1
+ while left < right and nums[right] == nums[right + 1]:
+ right -= 1
+ elif total < target:
+ left += 1
+ else:
+ right -= 1
+
+ return res
+```
+
+```java
+public class Solution {
+ public List> fourSum(int[] nums, int target) {
+ Arrays.sort(nums);
+ List> res = new ArrayList<>();
+ int n = nums.length;
+
+ for (int i = 0; i < n; i++) {
+ if (i > 0 && nums[i] == nums[i - 1]) continue;
+
+ for (int j = i + 1; j < n; j++) {
+ if (j > i + 1 && nums[j] == nums[j - 1]) continue;
+
+ int left = j + 1, right = n - 1;
+ while (left < right) {
+ long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
+ if (sum == target) {
+ res.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
+ left++;
+ right--;
+ while (left < right && nums[left] == nums[left - 1]) left++;
+ while (left < right && nums[right] == nums[right + 1]) right--;
+ } else if (sum < target) {
+ left++;
+ } else {
+ right--;
+ }
+ }
+ }
+ }
+ return res;
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ vector> fourSum(vector& nums, int target) {
+ vector> res;
+ int n = nums.size();
+ sort(nums.begin(), nums.end());
+
+ for (int i = 0; i < n; i++) {
+ if (i > 0 && nums[i] == nums[i - 1]) continue;
+
+ for (int j = i + 1; j < n; j++) {
+ if (j > i + 1 && nums[j] == nums[j - 1]) continue;
+
+ int left = j + 1, right = n - 1;
+ while (left < right) {
+ long long sum = (long long) nums[i] + nums[j] + nums[left] + nums[right];
+ if (sum == target) {
+ res.push_back({nums[i], nums[j], nums[left], nums[right]});
+ left++;
+ right--;
+ while (left < right && nums[left] == nums[left - 1]) left++;
+ while (left < right && nums[right] == nums[right + 1]) right--;
+ } else if (sum < target) {
+ left++;
+ } else {
+ right--;
+ }
+ }
+ }
+ }
+ return res;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} nums
+ * @param {number} target
+ * @return {number[][]}
+ */
+ fourSum(nums, target) {
+ nums.sort((a, b) => a - b);
+ const res = [];
+ const n = nums.length;
+
+ for (let i = 0; i < n; i++) {
+ if (i > 0 && nums[i] === nums[i - 1]) continue;
+
+ for (let j = i + 1; j < n; j++) {
+ if (j > i + 1 && nums[j] === nums[j - 1]) continue;
+
+ let left = j + 1, right = n - 1;
+ while (left < right) {
+ const sum = nums[i] + nums[j] + nums[left] + nums[right];
+ if (sum === target) {
+ res.push([nums[i], nums[j], nums[left], nums[right]]);
+ left++;
+ right--;
+ while (left < right && nums[left] === nums[left - 1]) left++;
+ while (left < right && nums[right] === nums[right + 1]) right--;
+ } else if (sum < target) {
+ left++;
+ } else {
+ right--;
+ }
+ }
+ }
+ }
+
+ return res;
+ }
+}
+```
+
+```csharp
+public class Solution {
+ public List> FourSum(int[] nums, int target) {
+ Array.Sort(nums);
+ List> res = new List>();
+ int n = nums.Length;
+
+ for (int i = 0; i < n; i++) {
+ if (i > 0 && nums[i] == nums[i - 1]) continue;
+
+ for (int j = i + 1; j < n; j++) {
+ if (j > i + 1 && nums[j] == nums[j - 1]) continue;
+
+ int left = j + 1, right = n - 1;
+ while (left < right) {
+ long sum = (long)nums[i] + nums[j] + nums[left] + nums[right];
+ if (sum == target) {
+ res.Add(new List { nums[i], nums[j], nums[left], nums[right] });
+ left++;
+ right--;
+ while (left < right && nums[left] == nums[left - 1]) left++;
+ while (left < right && nums[right] == nums[right + 1]) right--;
+ } else if (sum < target) {
+ left++;
+ } else {
+ right--;
+ }
+ }
+ }
+ }
+
+ return res;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n ^ 3)$
+* Space complexity:
+ * $O(1)$ or $O(n)$ space depending on the sorting algorithm.
+ * $O(m)$ space for the output array.
+
+---
+
+## 4. K-Sum + Two Pointers
+
+::tabs-start
+
+```python
+class Solution:
+ def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
+ nums.sort()
+ res, quad = [], []
+
+ def kSum(k, start, target):
+ if k == 2:
+ l, r = start, len(nums) - 1
+ while l < r:
+ if nums[l] + nums[r] < target:
+ l += 1
+ elif nums[l] + nums[r] > target:
+ r -= 1
+ else:
+ res.append(quad + [nums[l], nums[r]])
+ l += 1
+ r -= 1
+ while l < r and nums[l] == nums[l - 1]:
+ l += 1
+ while l < r and nums[r] == nums[r + 1]:
+ r -= 1
+ return
+
+ for i in range(start, len(nums) - k + 1):
+ if i > start and nums[i] == nums[i - 1]:
+ continue
+ quad.append(nums[i])
+ kSum(k - 1, i + 1, target - nums[i])
+ quad.pop()
+
+ kSum(4, 0, target)
+ return res
+```
+
+```java
+public class Solution {
+ private List> res;
+ private List quad;
+
+ public List> fourSum(int[] nums, int target) {
+ Arrays.sort(nums);
+ res = new ArrayList<>();
+ quad = new ArrayList<>();
+ kSum(nums, 4, 0, target);
+ return res;
+ }
+
+ private void kSum(int[] nums, int k, int start, long target) {
+ if (k == 2) {
+ int l = start, r = nums.length - 1;
+ while (l < r) {
+ long sum = nums[l] + nums[r];
+ if (sum < target) {
+ l++;
+ } else if (sum > target) {
+ r--;
+ } else {
+ res.add(new ArrayList<>(quad));
+ res.get(res.size() - 1).add(nums[l]);
+ res.get(res.size() - 1).add(nums[r]);
+ l++;
+ r--;
+ while (l < r && nums[l] == nums[l - 1]) l++;
+ while (l < r && nums[r] == nums[r + 1]) r--;
+ }
+ }
+ return;
+ }
+
+ for (int i = start; i < nums.length - k + 1; i++) {
+ if (i > start && nums[i] == nums[i - 1]) continue;
+ quad.add(nums[i]);
+ kSum(nums, k - 1, i + 1, target - nums[i]);
+ quad.remove(quad.size() - 1);
+ }
+ }
+}
+```
+
+```cpp
+class Solution {
+ vector> res;
+ vector quad;
+
+public:
+ vector> fourSum(vector& nums, int target) {
+ if (nums.size() < 4) return {};
+ sort(nums.begin(), nums.end());
+ kSum(nums, 4, 0, (long long) target);
+ return res;
+ }
+
+private:
+ void kSum(vector& nums, int k, int start, long long target) {
+ if (k == 2) {
+ int l = start, r = nums.size() - 1;
+ while (l < r) {
+ long long sum = (long long) nums[l] + nums[r];
+ if (sum < target) {
+ l++;
+ } else if (sum > target) {
+ r--;
+ } else {
+ quad.push_back(nums[l]);
+ quad.push_back(nums[r]);
+ res.push_back(quad);
+ quad.pop_back();
+ quad.pop_back();
+ l++;
+ r--;
+ while (l < r && nums[l] == nums[l - 1]) l++;
+ while (l < r && nums[r] == nums[r + 1]) r--;
+ }
+ }
+ return;
+ }
+
+ for (int i = start; i < nums.size() - k + 1; i++) {
+ if (i > start && nums[i] == nums[i - 1]) continue;
+ quad.push_back(nums[i]);
+ kSum(nums, k - 1, i + 1, target - nums[i]);
+ quad.pop_back();
+ }
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} nums
+ * @param {number} target
+ * @return {number[][]}
+ */
+ fourSum(nums, target) {
+ nums.sort((a, b) => a - b);
+ const res = [];
+ const quad = [];
+
+ const kSum = (k, start, target) => {
+ if (k === 2) {
+ let l = start, r = nums.length - 1;
+ while (l < r) {
+ const sum = nums[l] + nums[r];
+ if (sum < target) {
+ l++;
+ } else if (sum > target) {
+ r--;
+ } else {
+ res.push([...quad, nums[l], nums[r]]);
+ l++;
+ r--;
+ while (l < r && nums[l] === nums[l - 1]) l++;
+ while (l < r && nums[r] === nums[r + 1]) r--;
+ }
+ }
+ return;
+ }
+
+ for (let i = start; i < nums.length - k + 1; i++) {
+ if (i > start && nums[i] === nums[i - 1]) continue;
+ quad.push(nums[i]);
+ kSum(k - 1, i + 1, target - nums[i]);
+ quad.pop();
+ }
+ };
+
+ kSum(4, 0, target);
+ return res;
+ }
+}
+```
+
+```csharp
+public class Solution {
+ private List> res;
+ private List quad;
+
+ public List> FourSum(int[] nums, int target) {
+ Array.Sort(nums);
+ res = new List>();
+ quad = new List();
+ KSum(nums, 4, 0, target);
+ return res;
+ }
+
+ private void KSum(int[] nums, int k, int start, long target) {
+ if (k == 2) {
+ int l = start, r = nums.Length - 1;
+ while (l < r) {
+ long sum = (long)nums[l] + nums[r];
+ if (sum < target) {
+ l++;
+ } else if (sum > target) {
+ r--;
+ } else {
+ List newQuad = new List(quad);
+ newQuad.Add(nums[l]);
+ newQuad.Add(nums[r]);
+ res.Add(newQuad);
+ l++;
+ r--;
+ while (l < r && nums[l] == nums[l - 1]) l++;
+ while (l < r && nums[r] == nums[r + 1]) r--;
+ }
+ }
+ return;
+ }
+
+ for (int i = start; i < nums.Length - k + 1; i++) {
+ if (i > start && nums[i] == nums[i - 1]) continue;
+ quad.Add(nums[i]);
+ KSum(nums, k - 1, i + 1, target - nums[i]);
+ quad.RemoveAt(quad.Count - 1);
+ }
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n ^ 3)$
+* Space complexity:
+ * $O(1)$ or $O(n)$ space depending on the sorting algorithm.
+ * $O(m)$ space for the output array.
\ No newline at end of file
diff --git a/articles/accounts-merge.md b/articles/accounts-merge.md
new file mode 100644
index 000000000..15b8e9881
--- /dev/null
+++ b/articles/accounts-merge.md
@@ -0,0 +1,1165 @@
+## 1. Depth First Search
+
+::tabs-start
+
+```python
+class Solution:
+ def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
+ n = len(accounts)
+ emailIdx = {} # email -> id
+ emails = [] # set of emails of all accounts
+ emailToAcc = {} # email_index -> account_Id
+
+ m = 0
+ for accId, a in enumerate(accounts):
+ for i in range(1, len(a)):
+ email = a[i]
+ if email in emailIdx:
+ continue
+ emails.append(email)
+ emailIdx[email] = m
+ emailToAcc[m] = accId
+ m += 1
+
+ adj = [[] for _ in range(m)]
+ for a in accounts:
+ for i in range(2, len(a)):
+ id1 = emailIdx[a[i]]
+ id2 = emailIdx[a[i - 1]]
+ adj[id1].append(id2)
+ adj[id2].append(id1)
+
+ emailGroup = defaultdict(list) # index of acc -> list of emails
+ visited = [False] * m
+ def dfs(node, accId):
+ visited[node] = True
+ emailGroup[accId].append(emails[node])
+ for nei in adj[node]:
+ if not visited[nei]:
+ dfs(nei, accId)
+
+ for i in range(m):
+ if not visited[i]:
+ dfs(i, emailToAcc[i])
+
+ res = []
+ for accId in emailGroup:
+ name = accounts[accId][0]
+ res.append([name] + sorted(emailGroup[accId]))
+
+ return res
+```
+
+```java
+public class Solution {
+ private Map emailIdx = new HashMap<>(); // email -> id
+ private List emails = new ArrayList<>(); // set of emails of all accounts
+ private Map emailToAcc = new HashMap<>(); // email_index -> account_Id
+ private List> adj;
+ private Map> emailGroup = new HashMap<>(); // index of acc -> list of emails
+ private boolean[] visited;
+
+ public List> accountsMerge(List> accounts) {
+ int n = accounts.size();
+ int m = 0;
+
+ // Build email index and mappings
+ for (int accId = 0; accId < n; accId++) {
+ List account = accounts.get(accId);
+ for (int i = 1; i < account.size(); i++) {
+ String email = account.get(i);
+ if (!emailIdx.containsKey(email)) {
+ emails.add(email);
+ emailIdx.put(email, m);
+ emailToAcc.put(m, accId);
+ m++;
+ }
+ }
+ }
+
+ // Build adjacency list
+ adj = new ArrayList<>();
+ for (int i = 0; i < m; i++) {
+ adj.add(new ArrayList<>());
+ }
+ for (List account : accounts) {
+ for (int i = 2; i < account.size(); i++) {
+ int id1 = emailIdx.get(account.get(i));
+ int id2 = emailIdx.get(account.get(i - 1));
+ adj.get(id1).add(id2);
+ adj.get(id2).add(id1);
+ }
+ }
+
+ // Initialize visited array
+ visited = new boolean[m];
+
+ // DFS traversal
+ for (int i = 0; i < m; i++) {
+ if (!visited[i]) {
+ int accId = emailToAcc.get(i);
+ emailGroup.putIfAbsent(accId, new ArrayList<>());
+ dfs(i, accId);
+ }
+ }
+
+ // Build result
+ List> res = new ArrayList<>();
+ for (int accId : emailGroup.keySet()) {
+ List group = emailGroup.get(accId);
+ Collections.sort(group);
+ List merged = new ArrayList<>();
+ merged.add(accounts.get(accId).get(0));
+ merged.addAll(group);
+ res.add(merged);
+ }
+
+ return res;
+ }
+
+ private void dfs(int node, int accId) {
+ visited[node] = true;
+ emailGroup.get(accId).add(emails.get(node));
+ for (int neighbor : adj.get(node)) {
+ if (!visited[neighbor]) {
+ dfs(neighbor, accId);
+ }
+ }
+ }
+}
+```
+
+```cpp
+class Solution {
+ unordered_map emailIdx; // email -> id
+ vector emails; // set of emails of all accounts
+ unordered_map emailToAcc; // email_index -> account_Id
+ vector> adj;
+ unordered_map> emailGroup; // index of acc -> list of emails
+ vector visited;
+
+public:
+ vector> accountsMerge(vector>& accounts) {
+ int n = accounts.size();
+ int m = 0;
+
+ // Build email index and mappings
+ for (int accId = 0; accId < n; accId++) {
+ vector& account = accounts[accId];
+ for (int i = 1; i < account.size(); i++) {
+ string& email = account[i];
+ if (emailIdx.find(email) == emailIdx.end()) {
+ emails.push_back(email);
+ emailIdx[email] = m;
+ emailToAcc[m] = accId;
+ m++;
+ }
+ }
+ }
+
+ // Build adjacency list
+ adj.resize(m);
+ for (auto& account : accounts) {
+ for (int i = 2; i < account.size(); i++) {
+ int id1 = emailIdx[account[i]];
+ int id2 = emailIdx[account[i - 1]];
+ adj[id1].push_back(id2);
+ adj[id2].push_back(id1);
+ }
+ }
+
+ visited.resize(m, false);
+ // DFS traversal
+ for (int i = 0; i < m; i++) {
+ if (!visited[i]) {
+ int accId = emailToAcc[i];
+ dfs(i, accId);
+ }
+ }
+
+ // Build result
+ vector> res;
+ for (auto& [accId, group] : emailGroup) {
+ sort(group.begin(), group.end());
+ vector merged;
+ merged.push_back(accounts[accId][0]);
+ merged.insert(merged.end(), group.begin(), group.end());
+ res.push_back(merged);
+ }
+
+ return res;
+ }
+
+private:
+ void dfs(int node, int& accId) {
+ visited[node] = true;
+ emailGroup[accId].push_back(emails[node]);
+ for (int& neighbor : adj[node]) {
+ if (!visited[neighbor]) {
+ dfs(neighbor, accId);
+ }
+ }
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {string[][]} accounts
+ * @return {string[][]}
+ */
+ accountsMerge(accounts) {
+ const emailIdx = new Map(); // email -> id
+ const emails = []; // set of emails of all accounts
+ const emailToAcc = new Map(); // email_index -> account_Id
+ const adj = [];
+ const emailGroup = new Map(); // index of acc -> list of emails
+ let visited = [];
+
+ const n = accounts.length;
+ let m = 0;
+
+ // Build email index and mappings
+ for (let accId = 0; accId < n; accId++) {
+ const account = accounts[accId];
+ for (let i = 1; i < account.length; i++) {
+ const email = account[i];
+ if (!emailIdx.has(email)) {
+ emails.push(email);
+ emailIdx.set(email, m);
+ emailToAcc.set(m, accId);
+ m++;
+ }
+ }
+ }
+
+ // Build adjacency list
+ for (let i = 0; i < m; i++) {
+ adj.push([]);
+ }
+ for (const account of accounts) {
+ for (let i = 2; i < account.length; i++) {
+ const id1 = emailIdx.get(account[i]);
+ const id2 = emailIdx.get(account[i - 1]);
+ adj[id1].push(id2);
+ adj[id2].push(id1);
+ }
+ }
+
+ // Initialize visited array
+ visited = Array(m).fill(false);
+
+ // DFS traversal
+ const dfs = (node, accId) => {
+ visited[node] = true;
+ emailGroup.get(accId).push(emails[node]);
+ for (const neighbor of adj[node]) {
+ if (!visited[neighbor]) {
+ dfs(neighbor, accId);
+ }
+ }
+ };
+
+ for (let i = 0; i < m; i++) {
+ if (!visited[i]) {
+ const accId = emailToAcc.get(i);
+ if (!emailGroup.has(accId)) {
+ emailGroup.set(accId, []);
+ }
+ dfs(i, accId);
+ }
+ }
+
+ // Build result
+ const res = [];
+ for (const [accId, group] of emailGroup.entries()) {
+ group.sort();
+ const merged = [accounts[accId][0], ...group];
+ res.push(merged);
+ }
+
+ return res;
+ }
+}
+```
+
+```csharp
+public class Solution {
+ private Dictionary emailIdx = new Dictionary();
+ private List emails = new List();
+ private List> adj;
+ private bool[] visited;
+ private Dictionary> components = new Dictionary>();
+ private Dictionary componentName = new Dictionary();
+
+ public List> AccountsMerge(List> accounts) {
+ int m = 0;
+
+ for (int accId = 0; accId < accounts.Count; accId++) {
+ var account = accounts[accId];
+ for (int i = 1; i < account.Count; i++) {
+ string email = account[i];
+ if (!emailIdx.ContainsKey(email)) {
+ emailIdx[email] = m++;
+ emails.Add(email);
+ }
+ }
+ }
+
+ adj = new List>();
+ for (int i = 0; i < m; i++) adj.Add(new List());
+
+ foreach (var account in accounts) {
+ for (int i = 2; i < account.Count; i++) {
+ int u = emailIdx[account[i - 1]];
+ int v = emailIdx[account[i]];
+ adj[u].Add(v);
+ adj[v].Add(u);
+ }
+ }
+
+ visited = new bool[m];
+
+ foreach (var account in accounts) {
+ string name = account[0];
+ foreach (var email in account.Skip(1)) {
+ int idx = emailIdx[email];
+ if (!visited[idx]) {
+ components[idx] = new List();
+ componentName[idx] = name;
+ Dfs(idx, idx);
+ }
+ }
+ }
+
+ var res = new List>();
+ foreach (var kvp in components) {
+ var group = kvp.Value;
+ group.Sort(StringComparer.Ordinal);
+ var merged = new List { componentName[kvp.Key] };
+ merged.AddRange(group);
+ res.Add(merged);
+ }
+
+ return res;
+ }
+
+ private void Dfs(int node, int root) {
+ visited[node] = true;
+ components[root].Add(emails[node]);
+ foreach (int nei in adj[node]) {
+ if (!visited[nei]) {
+ Dfs(nei, root);
+ }
+ }
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O((n * m)\log (n * m))$
+* Space complexity: $O(n * m)$
+
+> Where $n$ is the number of accounts and $m$ is the number of emails.
+
+---
+
+## 2. Breadth First Search
+
+::tabs-start
+
+```python
+class Solution:
+ def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
+ n = len(accounts)
+ emailIdx = {} # email -> id
+ emails = [] # set of emails of all accounts
+ emailToAcc = {} # email_index -> account_Id
+
+ m = 0
+ for accId, a in enumerate(accounts):
+ for i in range(1, len(a)):
+ email = a[i]
+ if email in emailIdx:
+ continue
+ emails.append(email)
+ emailIdx[email] = m
+ emailToAcc[m] = accId
+ m += 1
+
+ adj = [[] for _ in range(m)]
+ for a in accounts:
+ for i in range(2, len(a)):
+ id1 = emailIdx[a[i]]
+ id2 = emailIdx[a[i - 1]]
+ adj[id1].append(id2)
+ adj[id2].append(id1)
+
+ emailGroup = defaultdict(list) # index of acc -> list of emails
+ visited = [False] * m
+
+ def bfs(start, accId):
+ queue = deque([start])
+ visited[start] = True
+ while queue:
+ node = queue.popleft()
+ emailGroup[accId].append(emails[node])
+ for nei in adj[node]:
+ if not visited[nei]:
+ visited[nei] = True
+ queue.append(nei)
+
+ for i in range(m):
+ if not visited[i]:
+ bfs(i, emailToAcc[i])
+
+ res = []
+ for accId in emailGroup:
+ name = accounts[accId][0]
+ res.append([name] + sorted(emailGroup[accId]))
+
+ return res
+```
+
+```java
+public class Solution {
+ private Map emailIdx = new HashMap<>(); // email -> id
+ private List emails = new ArrayList<>(); // set of emails of all accounts
+ private Map emailToAcc = new HashMap<>(); // email_index -> account_Id
+ private List> adj;
+ private Map> emailGroup = new HashMap<>(); // index of acc -> list of emails
+ private boolean[] visited;
+
+ public List> accountsMerge(List> accounts) {
+ int n = accounts.size();
+ int m = 0;
+
+ // Build email index and mappings
+ for (int accId = 0; accId < n; accId++) {
+ List account = accounts.get(accId);
+ for (int i = 1; i < account.size(); i++) {
+ String email = account.get(i);
+ if (!emailIdx.containsKey(email)) {
+ emails.add(email);
+ emailIdx.put(email, m);
+ emailToAcc.put(m, accId);
+ m++;
+ }
+ }
+ }
+
+ // Build adjacency list
+ adj = new ArrayList<>();
+ for (int i = 0; i < m; i++) {
+ adj.add(new ArrayList<>());
+ }
+ for (List account : accounts) {
+ for (int i = 2; i < account.size(); i++) {
+ int id1 = emailIdx.get(account.get(i));
+ int id2 = emailIdx.get(account.get(i - 1));
+ adj.get(id1).add(id2);
+ adj.get(id2).add(id1);
+ }
+ }
+
+ // Initialize visited array
+ visited = new boolean[m];
+
+ // BFS traversal
+ for (int i = 0; i < m; i++) {
+ if (!visited[i]) {
+ int accId = emailToAcc.get(i);
+ emailGroup.putIfAbsent(accId, new ArrayList<>());
+ bfs(i, accId);
+ }
+ }
+
+ // Build result
+ List> res = new ArrayList<>();
+ for (int accId : emailGroup.keySet()) {
+ List group = emailGroup.get(accId);
+ Collections.sort(group);
+ List merged = new ArrayList<>();
+ merged.add(accounts.get(accId).get(0));
+ merged.addAll(group);
+ res.add(merged);
+ }
+
+ return res;
+ }
+
+ private void bfs(int start, int accId) {
+ Queue queue = new LinkedList<>();
+ queue.offer(start);
+ visited[start] = true;
+
+ while (!queue.isEmpty()) {
+ int node = queue.poll();
+ emailGroup.get(accId).add(emails.get(node));
+ for (int neighbor : adj.get(node)) {
+ if (!visited[neighbor]) {
+ visited[neighbor] = true;
+ queue.offer(neighbor);
+ }
+ }
+ }
+ }
+}
+```
+
+```cpp
+class Solution {
+ unordered_map emailIdx; // email -> id
+ vector emails; // set of emails of all accounts
+ unordered_map emailToAcc; // email_index -> account_Id
+ vector> adj;
+ unordered_map> emailGroup; // index of acc -> list of emails
+ vector visited;
+
+public:
+ vector> accountsMerge(vector>& accounts) {
+ int n = accounts.size();
+ int m = 0;
+
+ // Build email index and mappings
+ for (int accId = 0; accId < n; accId++) {
+ vector& account = accounts[accId];
+ for (int i = 1; i < account.size(); i++) {
+ string& email = account[i];
+ if (emailIdx.find(email) == emailIdx.end()) {
+ emails.push_back(email);
+ emailIdx[email] = m;
+ emailToAcc[m] = accId;
+ m++;
+ }
+ }
+ }
+
+ // Build adjacency list
+ adj.resize(m);
+ for (auto& account : accounts) {
+ for (int i = 2; i < account.size(); i++) {
+ int id1 = emailIdx[account[i]];
+ int id2 = emailIdx[account[i - 1]];
+ adj[id1].push_back(id2);
+ adj[id2].push_back(id1);
+ }
+ }
+
+ visited.resize(m, false);
+ // BFS traversal
+ for (int i = 0; i < m; i++) {
+ if (!visited[i]) {
+ int accId = emailToAcc[i];
+ bfs(i, accId);
+ }
+ }
+
+ // Build result
+ vector> res;
+ for (auto& [accId, group] : emailGroup) {
+ sort(group.begin(), group.end());
+ vector merged;
+ merged.push_back(accounts[accId][0]);
+ merged.insert(merged.end(), group.begin(), group.end());
+ res.push_back(merged);
+ }
+
+ return res;
+ }
+
+private:
+ void bfs(int start, int accId) {
+ queue q;
+ q.push(start);
+ visited[start] = true;
+
+ while (!q.empty()) {
+ int node = q.front();
+ q.pop();
+ emailGroup[accId].push_back(emails[node]);
+ for (int& neighbor : adj[node]) {
+ if (!visited[neighbor]) {
+ visited[neighbor] = true;
+ q.push(neighbor);
+ }
+ }
+ }
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {string[][]} accounts
+ * @return {string[][]}
+ */
+ accountsMerge(accounts) {
+ const emailIdx = new Map(); // email -> id
+ const emails = []; // set of emails of all accounts
+ const emailToAcc = new Map(); // email_index -> account_Id
+ const adj = [];
+ const emailGroup = new Map(); // index of acc -> list of emails
+ let visited = [];
+
+ const n = accounts.length;
+ let m = 0;
+
+ // Build email index and mappings
+ for (let accId = 0; accId < n; accId++) {
+ const account = accounts[accId];
+ for (let i = 1; i < account.length; i++) {
+ const email = account[i];
+ if (!emailIdx.has(email)) {
+ emails.push(email);
+ emailIdx.set(email, m);
+ emailToAcc.set(m, accId);
+ m++;
+ }
+ }
+ }
+
+ // Build adjacency list
+ for (let i = 0; i < m; i++) {
+ adj.push([]);
+ }
+ for (const account of accounts) {
+ for (let i = 2; i < account.length; i++) {
+ const id1 = emailIdx.get(account[i]);
+ const id2 = emailIdx.get(account[i - 1]);
+ adj[id1].push(id2);
+ adj[id2].push(id1);
+ }
+ }
+
+ // Initialize visited array
+ visited = Array(m).fill(false);
+
+ // BFS traversal
+ const bfs = (start, accId) => {
+ const queue = new Queue([start]);
+ visited[start] = true;
+
+ while (!queue.isEmpty()) {
+ const node = queue.pop();
+ emailGroup.get(accId).push(emails[node]);
+ for (const neighbor of adj[node]) {
+ if (!visited[neighbor]) {
+ visited[neighbor] = true;
+ queue.push(neighbor);
+ }
+ }
+ }
+ };
+
+ for (let i = 0; i < m; i++) {
+ if (!visited[i]) {
+ const accId = emailToAcc.get(i);
+ if (!emailGroup.has(accId)) {
+ emailGroup.set(accId, []);
+ }
+ bfs(i, accId);
+ }
+ }
+
+ // Build result
+ const res = [];
+ for (const [accId, group] of emailGroup.entries()) {
+ group.sort();
+ const merged = [accounts[accId][0], ...group];
+ res.push(merged);
+ }
+
+ return res;
+ }
+}
+```
+
+```csharp
+public class Solution {
+ public List> AccountsMerge(List> accounts) {
+ int n = accounts.Count;
+ Dictionary emailIdx = new Dictionary();
+ List emails = new List();
+ Dictionary emailToAcc = new Dictionary();
+
+ int m = 0;
+ for (int accId = 0; accId < n; accId++) {
+ var account = accounts[accId];
+ for (int i = 1; i < account.Count; i++) {
+ string email = account[i];
+ if (!emailIdx.ContainsKey(email)) {
+ emailIdx[email] = m;
+ emails.Add(email);
+ emailToAcc[m] = accId;
+ m++;
+ }
+ }
+ }
+
+ List> adj = new List>();
+ for (int i = 0; i < m; i++) adj.Add(new List());
+
+ foreach (var account in accounts) {
+ for (int i = 2; i < account.Count; i++) {
+ int id1 = emailIdx[account[i]];
+ int id2 = emailIdx[account[i - 1]];
+ adj[id1].Add(id2);
+ adj[id2].Add(id1);
+ }
+ }
+
+ Dictionary> emailGroup = new Dictionary>();
+ bool[] visited = new bool[m];
+
+ void Bfs(int start, int accId) {
+ Queue queue = new Queue();
+ queue.Enqueue(start);
+ visited[start] = true;
+
+ if (!emailGroup.ContainsKey(accId))
+ emailGroup[accId] = new List();
+
+ while (queue.Count > 0) {
+ int node = queue.Dequeue();
+ emailGroup[accId].Add(emails[node]);
+
+ foreach (int nei in adj[node]) {
+ if (!visited[nei]) {
+ visited[nei] = true;
+ queue.Enqueue(nei);
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < m; i++) {
+ if (!visited[i]) {
+ Bfs(i, emailToAcc[i]);
+ }
+ }
+
+ List> res = new List>();
+ foreach (var kvp in emailGroup) {
+ int accId = kvp.Key;
+ string name = accounts[accId][0];
+ List merged = new List { name };
+ kvp.Value.Sort(StringComparer.Ordinal);
+ merged.AddRange(kvp.Value);
+ res.Add(merged);
+ }
+
+ return res;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O((n * m)\log (n * m))$
+* Space complexity: $O(n * m)$
+
+> Where $n$ is the number of accounts and $m$ is the number of emails.
+
+---
+
+## 3. Disjoint Set Union
+
+::tabs-start
+
+```python
+class UnionFind:
+ def __init__(self, n):
+ self.par = [i for i in range(n)]
+ self.rank = [1] * n
+
+ def find(self, x):
+ while x != self.par[x]:
+ self.par[x] = self.par[self.par[x]]
+ x = self.par[x]
+ return x
+
+ def union(self, x1, x2):
+ p1, p2 = self.find(x1), self.find(x2)
+ if p1 == p2:
+ return False
+ if self.rank[p1] > self.rank[p2]:
+ self.par[p2] = p1
+ self.rank[p1] += self.rank[p2]
+ else:
+ self.par[p1] = p2
+ self.rank[p2] += self.rank[p1]
+ return True
+
+class Solution:
+ def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:
+ uf = UnionFind(len(accounts))
+ emailToAcc = {} # email -> index of acc
+
+ for i, a in enumerate(accounts):
+ for e in a[1:]:
+ if e in emailToAcc:
+ uf.union(i, emailToAcc[e])
+ else:
+ emailToAcc[e] = i
+
+ emailGroup = defaultdict(list) # index of acc -> list of emails
+ for e, i in emailToAcc.items():
+ leader = uf.find(i)
+ emailGroup[leader].append(e)
+
+ res = []
+ for i, emails in emailGroup.items():
+ name = accounts[i][0]
+ res.append([name] + sorted(emailGroup[i]))
+ return res
+```
+
+```java
+class UnionFind {
+ private int[] parent;
+ private int[] rank;
+
+ public UnionFind(int n) {
+ parent = new int[n];
+ rank = new int[n];
+ for (int i = 0; i < n; i++) {
+ parent[i] = i;
+ rank[i] = 1;
+ }
+ }
+
+ public int find(int x) {
+ if (x != parent[x]) {
+ parent[x] = find(parent[x]);
+ }
+ return parent[x];
+ }
+
+ public boolean union(int x1, int x2) {
+ int p1 = find(x1);
+ int p2 = find(x2);
+ if (p1 == p2) {
+ return false;
+ }
+ if (rank[p1] > rank[p2]) {
+ parent[p2] = p1;
+ rank[p1] += rank[p2];
+ } else {
+ parent[p1] = p2;
+ rank[p2] += rank[p1];
+ }
+ return true;
+ }
+}
+
+public class Solution {
+ public List> accountsMerge(List> accounts) {
+ int n = accounts.size();
+ UnionFind uf = new UnionFind(n);
+ Map emailToAcc = new HashMap<>(); // email -> index of acc
+
+ // Build union-find structure
+ for (int i = 0; i < n; i++) {
+ List account = accounts.get(i);
+ for (int j = 1; j < account.size(); j++) {
+ String email = account.get(j);
+ if (emailToAcc.containsKey(email)) {
+ uf.union(i, emailToAcc.get(email));
+ } else {
+ emailToAcc.put(email, i);
+ }
+ }
+ }
+
+ // Group emails by leader account
+ Map> emailGroup = new HashMap<>(); // index of acc -> list of emails
+ for (Map.Entry entry : emailToAcc.entrySet()) {
+ String email = entry.getKey();
+ int accId = entry.getValue();
+ int leader = uf.find(accId);
+ emailGroup.putIfAbsent(leader, new ArrayList<>());
+ emailGroup.get(leader).add(email);
+ }
+
+ // Build result
+ List> res = new ArrayList<>();
+ for (Map.Entry> entry : emailGroup.entrySet()) {
+ int accId = entry.getKey();
+ List emails = entry.getValue();
+ Collections.sort(emails);
+ List merged = new ArrayList<>();
+ merged.add(accounts.get(accId).get(0)); // Add account name
+ merged.addAll(emails);
+ res.add(merged);
+ }
+
+ return res;
+ }
+}
+```
+
+```cpp
+class UnionFind {
+ vector parent;
+ vector rank;
+
+public:
+ UnionFind(int n) {
+ parent.resize(n);
+ rank.resize(n, 1);
+ for (int i = 0; i < n; i++) {
+ parent[i] = i;
+ }
+ }
+
+ int find(int x) {
+ if (x != parent[x]) {
+ parent[x] = find(parent[x]);
+ }
+ return parent[x];
+ }
+
+ bool unionSets(int x1, int x2) {
+ int p1 = find(x1);
+ int p2 = find(x2);
+ if (p1 == p2) {
+ return false;
+ }
+ if (rank[p1] > rank[p2]) {
+ parent[p2] = p1;
+ rank[p1] += rank[p2];
+ } else {
+ parent[p1] = p2;
+ rank[p2] += rank[p1];
+ }
+ return true;
+ }
+};
+
+class Solution {
+public:
+ vector> accountsMerge(vector>& accounts) {
+ int n = accounts.size();
+ UnionFind uf(n);
+ unordered_map emailToAcc; // email -> index of acc
+
+ // Build union-find structure
+ for (int i = 0; i < n; i++) {
+ for (int j = 1; j < accounts[i].size(); j++) {
+ const string& email = accounts[i][j];
+ if (emailToAcc.count(email)) {
+ uf.unionSets(i, emailToAcc[email]);
+ } else {
+ emailToAcc[email] = i;
+ }
+ }
+ }
+
+ // Group emails by leader account
+ map> emailGroup; // index of acc -> list of emails
+ for (const auto& [email, accId] : emailToAcc) {
+ int leader = uf.find(accId);
+ emailGroup[leader].push_back(email);
+ }
+
+ // Build result
+ vector> res;
+ for (auto& [accId, emails] : emailGroup) {
+ sort(emails.begin(), emails.end());
+ vector merged;
+ merged.push_back(accounts[accId][0]);
+ merged.insert(merged.end(), emails.begin(), emails.end());
+ res.push_back(merged);
+ }
+
+ return res;
+ }
+};
+```
+
+```javascript
+class UnionFind {
+ /**
+ * @constructor
+ * @param {number} n
+ */
+ constructor(n) {
+ this.parent = Array.from({ length: n }, (_, i) => i);
+ this.rank = Array(n).fill(1);
+ }
+
+ /**
+ * @param {number} x
+ * @return {number}
+ */
+ find(x) {
+ if (x !== this.parent[x]) {
+ this.parent[x] = this.find(this.parent[x]);
+ }
+ return this.parent[x];
+ }
+
+ /**
+ * @param {number} x1
+ * @param {number} x2
+ * @return {boolean}
+ */
+ union(x1, x2) {
+ const p1 = this.find(x1);
+ const p2 = this.find(x2);
+ if (p1 === p2) {
+ return false;
+ }
+ if (this.rank[p1] > this.rank[p2]) {
+ this.parent[p2] = p1;
+ this.rank[p1] += this.rank[p2];
+ } else {
+ this.parent[p1] = p2;
+ this.rank[p2] += this.rank[p1];
+ }
+ return true;
+ }
+}
+
+class Solution {
+ /**
+ * @param {string[][]} accounts
+ * @return {string[][]}
+ */
+ accountsMerge(accounts) {
+ const n = accounts.length;
+ const uf = new UnionFind(n);
+ const emailToAcc = new Map(); // email -> index of acc
+
+ // Build union-find structure
+ for (let i = 0; i < n; i++) {
+ for (let j = 1; j < accounts[i].length; j++) {
+ const email = accounts[i][j];
+ if (emailToAcc.has(email)) {
+ uf.union(i, emailToAcc.get(email));
+ } else {
+ emailToAcc.set(email, i);
+ }
+ }
+ }
+
+ // Group emails by leader account
+ const emailGroup = new Map(); // index of acc -> list of emails
+ for (const [email, accId] of emailToAcc.entries()) {
+ const leader = uf.find(accId);
+ if (!emailGroup.has(leader)) {
+ emailGroup.set(leader, []);
+ }
+ emailGroup.get(leader).push(email);
+ }
+
+ // Build result
+ const res = [];
+ for (const [accId, emails] of emailGroup.entries()) {
+ emails.sort();
+ const merged = [accounts[accId][0], ...emails];
+ res.push(merged);
+ }
+
+ return res;
+ }
+}
+```
+
+```csharp
+public class UnionFind {
+ private int[] parent;
+ private int[] rank;
+
+ public UnionFind(int n) {
+ parent = new int[n];
+ rank = new int[n];
+ for (int i = 0; i < n; i++) {
+ parent[i] = i;
+ rank[i] = 1;
+ }
+ }
+
+ public int Find(int x) {
+ if (x != parent[x]) {
+ parent[x] = Find(parent[x]);
+ }
+ return parent[x];
+ }
+
+ public bool Union(int x, int y) {
+ int rootX = Find(x);
+ int rootY = Find(y);
+
+ if (rootX == rootY) return false;
+
+ if (rank[rootX] > rank[rootY]) {
+ parent[rootY] = rootX;
+ rank[rootX] += rank[rootY];
+ } else {
+ parent[rootX] = rootY;
+ rank[rootY] += rank[rootX];
+ }
+
+ return true;
+ }
+}
+
+public class Solution {
+ public List> AccountsMerge(List> accounts) {
+ int n = accounts.Count;
+ UnionFind uf = new UnionFind(n);
+ Dictionary emailToAcc = new Dictionary();
+
+ for (int i = 0; i < n; i++) {
+ for (int j = 1; j < accounts[i].Count; j++) {
+ string email = accounts[i][j];
+ if (emailToAcc.ContainsKey(email)) {
+ uf.Union(i, emailToAcc[email]);
+ } else {
+ emailToAcc[email] = i;
+ }
+ }
+ }
+
+ Dictionary> emailGroup = new Dictionary>();
+ foreach (var kvp in emailToAcc) {
+ string email = kvp.Key;
+ int leader = uf.Find(kvp.Value);
+ if (!emailGroup.ContainsKey(leader)) {
+ emailGroup[leader] = new List();
+ }
+ emailGroup[leader].Add(email);
+ }
+
+ List> res = new List>();
+ foreach (var kvp in emailGroup) {
+ int accId = kvp.Key;
+ List emails = kvp.Value;
+ emails.Sort(StringComparer.Ordinal);
+ List merged = new List { accounts[accId][0] };
+ merged.AddRange(emails);
+ res.Add(merged);
+ }
+
+ return res;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O((n * m)\log (n * m))$
+* Space complexity: $O(n * m)$
+
+> Where $n$ is the number of accounts and $m$ is the number of emails.
\ No newline at end of file
diff --git a/articles/add-binary.md b/articles/add-binary.md
new file mode 100644
index 000000000..424adb990
--- /dev/null
+++ b/articles/add-binary.md
@@ -0,0 +1,240 @@
+## 1. Iteration
+
+::tabs-start
+
+```python
+class Solution:
+ def addBinary(self, a: str, b: str) -> str:
+ res = ""
+ carry = 0
+
+ a, b = a[::-1], b[::-1]
+ for i in range(max(len(a), len(b))):
+ digitA = ord(a[i]) - ord("0") if i < len(a) else 0
+ digitB = ord(b[i]) - ord("0") if i < len(b) else 0
+
+ total = digitA + digitB + carry
+ char = str(total % 2)
+ res = char + res
+ carry = total // 2
+
+ if carry:
+ res = "1" + res
+
+ return res
+```
+
+```java
+public class Solution {
+ public String addBinary(String a, String b) {
+ StringBuilder res = new StringBuilder();
+ int carry = 0;
+
+ StringBuilder sa = new StringBuilder(a).reverse();
+ StringBuilder sb = new StringBuilder(b).reverse();
+
+ for (int i = 0; i < Math.max(sa.length(), sb.length()); i++) {
+ int digitA = i < sa.length() ? sa.charAt(i) - '0' : 0;
+ int digitB = i < sb.length() ? sb.charAt(i) - '0' : 0;
+
+ int total = digitA + digitB + carry;
+ char c = (char)((total % 2) + '0');
+ res.append(c);
+ carry = total / 2;
+ }
+
+ if (carry > 0) {
+ res.append('1');
+ }
+
+ return res.reverse().toString();
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ string addBinary(string a, string b) {
+ string res = "";
+ int carry = 0;
+
+ reverse(a.begin(), a.end());
+ reverse(b.begin(), b.end());
+
+ for (int i = 0; i < max(a.length(), b.length()); i++) {
+ int digitA = i < a.length() ? a[i] - '0' : 0;
+ int digitB = i < b.length() ? b[i] - '0' : 0;
+
+ int total = digitA + digitB + carry;
+ char c = (total % 2) + '0';
+ res += c;
+ carry = total / 2;
+ }
+
+ if (carry) {
+ res += '1';
+ }
+ reverse(res.begin(), res.end());
+ return res;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {string} a
+ * @param {string} b
+ * @return {string}
+ */
+ addBinary(a, b) {
+ let res = [];
+ let carry = 0;
+
+ a = a.split("").reverse().join("");
+ b = b.split("").reverse().join("");
+
+ for (let i = 0; i < Math.max(a.length, b.length); i++) {
+ const digitA = i < a.length ? a[i] - '0' : 0;
+ const digitB = i < b.length ? b[i] - '0' : 0;
+
+ const total = digitA + digitB + carry;
+ const char = (total % 2).toString();
+ res.push(char)
+ carry = Math.floor(total / 2);
+ }
+
+ if (carry) {
+ res.push('1');
+ }
+ res.reverse()
+ return res.join('');
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(max(m, n))$
+* Space complexity: $O(m + n)$
+
+> Where $m$ and $n$ are the lengths of the strings $a$ and $b$ respectively.
+
+---
+
+## 2. Iteration (Optimal)
+
+::tabs-start
+
+```python
+class Solution:
+ def addBinary(self, a: str, b: str) -> str:
+ res = []
+ carry = 0
+
+ i, j = len(a) - 1, len(b) - 1
+ while i >= 0 or j >= 0 or carry > 0:
+ digitA = int(a[i]) if i >= 0 else 0
+ digitB = int(b[j]) if j >= 0 else 0
+
+ total = digitA + digitB + carry
+ res.append(total % 2)
+ carry = total // 2
+
+ i -= 1
+ j -= 1
+
+ res.reverse()
+ return ''.join(map(str, res))
+```
+
+```java
+public class Solution {
+ public String addBinary(String a, String b) {
+ StringBuilder res = new StringBuilder();
+ int carry = 0;
+
+ int i = a.length() - 1, j = b.length() - 1;
+ while (i >= 0 || j >= 0 || carry > 0) {
+ int digitA = i >= 0 ? a.charAt(i) - '0' : 0;
+ int digitB = j >= 0 ? b.charAt(j) - '0' : 0;
+
+ int total = digitA + digitB + carry;
+ res.append(total % 2);
+ carry = total / 2;
+
+ i--;
+ j--;
+ }
+
+ return res.reverse().toString();
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ string addBinary(string a, string b) {
+ string res = "";
+ int carry = 0;
+
+ int i = a.size() - 1, j = b.size() - 1;
+ while (i >= 0 || j >= 0 || carry > 0) {
+ int digitA = i >= 0 ? a[i] - '0' : 0;
+ int digitB = j >= 0 ? b[j] - '0' : 0;
+
+ int total = digitA + digitB + carry;
+ res += (total % 2) + '0';
+ carry = total / 2;
+
+ i--;
+ j--;
+ }
+
+ reverse(res.begin(), res.end());
+ return res;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {string} a
+ * @param {string} b
+ * @return {string}
+ */
+ addBinary(a, b) {
+ let res = [];
+ let carry = 0;
+
+ let i = a.length - 1, j = b.length - 1;
+ while (i >= 0 || j >= 0 || carry > 0) {
+ const digitA = i >= 0 ? a[i] - "0" : 0;
+ const digitB = j >= 0 ? b[j] - "0" : 0;
+
+ const total = digitA + digitB + carry;
+ res.push(total % 2);
+ carry = Math.floor(total / 2);
+
+ i--;
+ j--;
+ }
+ res.reverse()
+ return res.join('');
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(max(m, n))$
+* Space complexity: $O(max(m, n))$
+
+> Where $m$ and $n$ are the lengths of the strings $a$ and $b$ respectively.
\ No newline at end of file
diff --git a/articles/add-to-array-form-of-integer.md b/articles/add-to-array-form-of-integer.md
new file mode 100644
index 000000000..ecab6ca84
--- /dev/null
+++ b/articles/add-to-array-form-of-integer.md
@@ -0,0 +1,217 @@
+## 1. Reverse and Add
+
+::tabs-start
+
+```python
+class Solution:
+ def addToArrayForm(self, num: List[int], k: int) -> List[int]:
+ num.reverse()
+ i = 0
+ while k:
+ digit = k % 10
+ if i < len(num):
+ num[i] += digit
+ else:
+ num.append(digit)
+ carry = num[i] // 10
+ num[i] %= 10
+ k //= 10
+ k += carry
+ i += 1
+ num.reverse()
+ return num
+```
+
+```java
+public class Solution {
+ public List addToArrayForm(int[] num, int k) {
+ List result = new ArrayList<>();
+ for (int i = num.length - 1; i >= 0; i--) {
+ k += num[i];
+ result.add(k % 10);
+ k /= 10;
+ }
+ while (k > 0) {
+ result.add(k % 10);
+ k /= 10;
+ }
+ Collections.reverse(result);
+ return result;
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ vector addToArrayForm(vector& num, int k) {
+ reverse(num.begin(), num.end());
+ int i = 0;
+ while (k) {
+ int digit = k % 10;
+ if (i < num.size()) {
+ num[i] += digit;
+ } else {
+ num.push_back(digit);
+ }
+ int carry = num[i] / 10;
+ num[i] %= 10;
+ k /= 10;
+ k += carry;
+ i++;
+ }
+ reverse(num.begin(), num.end());
+ return num;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} num
+ * @param {number} k
+ * @return {number[]}
+ */
+ addToArrayForm(num, k) {
+ num.reverse();
+ let i = 0;
+ while (k > 0) {
+ const digit = k % 10;
+ if (i < num.length) {
+ num[i] += digit;
+ } else {
+ num.push(digit);
+ }
+ const carry = Math.floor(num[i] / 10);
+ num[i] %= 10;
+ k = Math.floor(k / 10) + carry;
+ i++;
+ }
+ num.reverse();
+ return num;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(max(n, m))$
+* Space complexity: $O(n)$.
+
+> Where $n$ is the size of the array $num$ and $m$ is the number of digits in $k$.
+
+---
+
+## 2. Without Reverse()
+
+::tabs-start
+
+```python
+class Solution:
+ def addToArrayForm(self, num: List[int], k: int) -> List[int]:
+ from collections import deque
+ result = deque()
+ i = len(num) - 1
+ carry = 0
+
+ while i >= 0 or k > 0 or carry > 0:
+ digit = k % 10
+ sum_val = carry + (num[i] if i >= 0 else 0) + digit
+
+ result.appendleft(sum_val % 10)
+ carry = sum_val // 10
+
+ k //= 10
+ i -= 1
+
+ return list(result)
+```
+
+```java
+public class Solution {
+ public List addToArrayForm(int[] num, int k) {
+ LinkedList result = new LinkedList<>();
+ int carry = 0, i = num.length - 1;
+
+ while (i >= 0 || k > 0 || carry > 0) {
+ int digit = k % 10;
+ int sum = carry + (i >= 0 ? num[i] : 0) + digit;
+
+ result.addFirst(sum % 10);
+ carry = sum / 10;
+
+ k /= 10;
+ i--;
+ }
+
+ return result;
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ vector addToArrayForm(vector& num, int k) {
+ list result;
+ int carry = 0, i = num.size() - 1;
+
+ while (i >= 0 || k > 0 || carry > 0) {
+ int digit = k % 10;
+ int sum = carry + (i >= 0 ? num[i] : 0) + digit;
+
+ result.push_front(sum % 10);
+ carry = sum / 10;
+
+ k /= 10;
+ i--;
+ }
+
+ return vector(result.begin(), result.end());
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} num
+ * @param {number} k
+ * @return {number[]}
+ */
+ addToArrayForm(num, k) {
+ let res = new Deque();
+ let carry = 0, i = num.length - 1;
+
+ while (i >= 0 || k > 0 || carry > 0) {
+ const digit = k % 10;
+ const sum = carry + (i >= 0 ? num[i] : 0) + digit;
+
+ res.pushFront(sum % 10);
+ carry = Math.floor(sum / 10);
+
+ k = Math.floor(k / 10);
+ i--;
+ }
+
+ const resultArray = [];
+ while (!res.isEmpty()) {
+ resultArray.push(res.popFront());
+ }
+
+ return resultArray;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(max(n, m))$
+* Space complexity: $O(n)$
+
+> Where $n$ is the size of the array $num$ and $m$ is the number of digits in $k$.
\ No newline at end of file
diff --git a/articles/add-two-numbers.md b/articles/add-two-numbers.md
index 0fb91cffb..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
@@ -310,7 +344,7 @@ class Solution {
* Time complexity: $O(m + n)$
* Space complexity: $O(m + n)$
-> Where $m$ is the length $l1$ and $n$ is the length of $l2$.
+> Where $m$ is the length of $l1$ and $n$ is the length of $l2$.
---
@@ -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 $l1$ and $n$ is the length of $l2$.
\ No newline at end of file
+> Where $m$ is the length of $l1$ and $n$ is the length of $l2$.
\ No newline at end of file
diff --git a/articles/all-possible-full-binary-trees.md b/articles/all-possible-full-binary-trees.md
new file mode 100644
index 000000000..1e75b0293
--- /dev/null
+++ b/articles/all-possible-full-binary-trees.md
@@ -0,0 +1,693 @@
+## 1. Recursion
+
+::tabs-start
+
+```python
+# Definition for a binary tree node.
+# class TreeNode:
+# def __init__(self, val=0, left=None, right=None):
+# self.val = val
+# self.left = left
+# self.right = right
+class Solution:
+ def allPossibleFBT(self, n: int) -> List[Optional[TreeNode]]:
+ def backtrack(n):
+ if n == 0:
+ return []
+ if n == 1:
+ return [TreeNode(0)]
+
+ res = []
+ for l in range(n):
+ r = n - 1 - l
+ leftTrees, rightTrees = backtrack(l), backtrack(r)
+
+ for t1 in leftTrees:
+ for t2 in rightTrees:
+ res.append(TreeNode(0, t1, t2))
+ return res
+
+ return backtrack(n)
+```
+
+```java
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * int val;
+ * TreeNode left;
+ * TreeNode right;
+ * TreeNode() {}
+ * TreeNode(int val) { this.val = val; }
+ * TreeNode(int val, TreeNode left, TreeNode right) {
+ * this.val = val;
+ * this.left = left;
+ * this.right = right;
+ * }
+ * }
+ */
+public class Solution {
+ public List allPossibleFBT(int n) {
+ return backtrack(n);
+ }
+
+ private List backtrack(int n) {
+ if (n == 0) {
+ return new ArrayList<>();
+ }
+ if (n == 1) {
+ return Arrays.asList(new TreeNode(0));
+ }
+
+ List res = new ArrayList<>();
+ for (int l = 0; l < n; l++) {
+ int r = n - 1 - l;
+ List leftTrees = backtrack(l);
+ List rightTrees = backtrack(r);
+
+ for (TreeNode t1 : leftTrees) {
+ for (TreeNode t2 : rightTrees) {
+ res.add(new TreeNode(0, t1, t2));
+ }
+ }
+ }
+ return res;
+ }
+}
+```
+
+```cpp
+/**
+ * Definition for a binary tree node.
+ * struct TreeNode {
+ * int val;
+ * TreeNode *left;
+ * TreeNode *right;
+ * TreeNode() : val(0), left(nullptr), right(nullptr) {}
+ * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
+ * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
+ * };
+ */
+class Solution {
+public:
+ vector allPossibleFBT(int n) {
+ return backtrack(n);
+ }
+
+private:
+ vector backtrack(int n) {
+ if (n == 0) {
+ return {};
+ }
+ if (n == 1) {
+ return {new TreeNode(0)};
+ }
+
+ vector res;
+ for (int l = 0; l < n; l++) {
+ int r = n - 1 - l;
+ vector leftTrees = backtrack(l);
+ vector rightTrees = backtrack(r);
+
+ for (auto& t1 : leftTrees) {
+ for (auto& t2 : rightTrees) {
+ res.push_back(new TreeNode(0, t1, t2));
+ }
+ }
+ }
+ return res;
+ }
+};
+```
+
+```javascript
+/**
+ * Definition for a binary tree node.
+ * class TreeNode {
+ * constructor(val = 0, left = null, right = null) {
+ * this.val = val;
+ * this.left = left;
+ * this.right = right;
+ * }
+ * }
+ */
+class Solution {
+ /**
+ * @param {number} n
+ * @return {TreeNode[]}
+ */
+ allPossibleFBT(n) {
+ const backtrack = (n) => {
+ if (n === 0) {
+ return [];
+ }
+ if (n === 1) {
+ return [new TreeNode(0)];
+ }
+
+ let res = [];
+ for (let l = 0; l < n; l++) {
+ let r = n - 1 - l;
+ let leftTrees = backtrack(l);
+ let rightTrees = backtrack(r);
+
+ for (let t1 of leftTrees) {
+ for (let t2 of rightTrees) {
+ res.push(new TreeNode(0, t1, t2));
+ }
+ }
+ }
+ return res;
+ };
+
+ return backtrack(n);
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(2 ^ n)$
+* Space complexity: $O(n * 2 ^ n)$
+
+---
+
+## 2. Recursion (Optimal)
+
+::tabs-start
+
+```python
+# Definition for a binary tree node.
+# class TreeNode:
+# def __init__(self, val=0, left=None, right=None):
+# self.val = val
+# self.left = left
+# self.right = right
+class Solution:
+ def allPossibleFBT(self, n: int) -> List[Optional[TreeNode]]:
+ if n % 2 == 0:
+ return []
+ if n == 1:
+ return [TreeNode(0)]
+
+ res = []
+ for left in range(1, n, 2):
+ leftSubTree = self.allPossibleFBT(left)
+ rightSubTree = self.allPossibleFBT(n - 1 - left)
+ for l in leftSubTree:
+ for r in rightSubTree:
+ root = TreeNode(0, l, r)
+ res.append(root)
+ return res
+```
+
+```java
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * int val;
+ * TreeNode left;
+ * TreeNode right;
+ * TreeNode() {}
+ * TreeNode(int val) { this.val = val; }
+ * TreeNode(int val, TreeNode left, TreeNode right) {
+ * this.val = val;
+ * this.left = left;
+ * this.right = right;
+ * }
+ * }
+ */
+public class Solution {
+ public List allPossibleFBT(int n) {
+ if (n % 2 == 0) {
+ return new ArrayList<>();
+ }
+ if (n == 1) {
+ return Arrays.asList(new TreeNode(0));
+ }
+
+ List res = new ArrayList<>();
+ for (int left = 1; left < n; left += 2) {
+ List leftSubTree = allPossibleFBT(left);
+ List rightSubTree = allPossibleFBT(n - 1 - left);
+ for (TreeNode l : leftSubTree) {
+ for (TreeNode r : rightSubTree) {
+ TreeNode root = new TreeNode(0, l, r);
+ res.add(root);
+ }
+ }
+ }
+ return res;
+ }
+}
+```
+
+```cpp
+/**
+ * Definition for a binary tree node.
+ * struct TreeNode {
+ * int val;
+ * TreeNode *left;
+ * TreeNode *right;
+ * TreeNode() : val(0), left(nullptr), right(nullptr) {}
+ * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
+ * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
+ * };
+ */
+class Solution {
+public:
+ vector allPossibleFBT(int n) {
+ if (n % 2 == 0) {
+ return {};
+ }
+ if (n == 1) {
+ return {new TreeNode(0)};
+ }
+
+ vector res;
+ for (int left = 1; left < n; left += 2) {
+ vector leftSubTree = allPossibleFBT(left);
+ vector rightSubTree = allPossibleFBT(n - 1 - left);
+ for (auto& l : leftSubTree) {
+ for (auto& r : rightSubTree) {
+ TreeNode* root = new TreeNode(0, l, r);
+ res.push_back(root);
+ }
+ }
+ }
+ return res;
+ }
+};
+```
+
+```javascript
+/**
+ * Definition for a binary tree node.
+ * class TreeNode {
+ * constructor(val = 0, left = null, right = null) {
+ * this.val = val;
+ * this.left = left;
+ * this.right = right;
+ * }
+ * }
+ */
+class Solution {
+ /**
+ * @param {number} n
+ * @return {TreeNode[]}
+ */
+ allPossibleFBT(n) {
+ if (n % 2 === 0) {
+ return [];
+ }
+ if (n === 1) {
+ return [new TreeNode(0)];
+ }
+
+ let res = [];
+ for (let left = 1; left < n; left += 2) {
+ let leftSubTree = this.allPossibleFBT(left);
+ let rightSubTree = this.allPossibleFBT(n - 1 - left);
+ for (let l of leftSubTree) {
+ for (let r of rightSubTree) {
+ let root = new TreeNode(0, l, r);
+ res.push(root);
+ }
+ }
+ }
+ return res;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(2 ^ n)$
+* Space complexity: $O(n * 2 ^ n)$
+
+---
+
+## 3. Dynamic Programming (Top-Down)
+
+::tabs-start
+
+```python
+# Definition for a binary tree node.
+# class TreeNode:
+# def __init__(self, val=0, left=None, right=None):
+# self.val = val
+# self.left = left
+# self.right = right
+class Solution:
+ def allPossibleFBT(self, n: int) -> List[Optional[TreeNode]]:
+ dp = {}
+
+ def dfs(n):
+ if n % 2 == 0:
+ return []
+ if n == 1:
+ return [TreeNode(0)]
+ if n in dp:
+ return dp[n]
+
+ res = []
+ for left in range(1, n, 2):
+ leftSubTree = dfs(left)
+ rightSubTree = dfs(n - 1 - left)
+ for l in leftSubTree:
+ for r in rightSubTree:
+ res.append(TreeNode(0, l, r))
+
+ dp[n] = res
+ return res
+
+ return dfs(n)
+```
+
+```java
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * int val;
+ * TreeNode left;
+ * TreeNode right;
+ * TreeNode() {}
+ * TreeNode(int val) { this.val = val; }
+ * TreeNode(int val, TreeNode left, TreeNode right) {
+ * this.val = val;
+ * this.left = left;
+ * this.right = right;
+ * }
+ * }
+ */
+public class Solution {
+ private List[] dp;
+
+ public List allPossibleFBT(int n) {
+ dp = new ArrayList[n + 1];
+ return dfs(n);
+ }
+
+ private List dfs(int n) {
+ if (n % 2 == 0) {
+ return new ArrayList<>();
+ }
+ if (n == 1) {
+ return Arrays.asList(new TreeNode(0));
+ }
+ if (dp[n] != null) {
+ return dp[n];
+ }
+
+ List res = new ArrayList<>();
+ for (int left = 1; left < n; left += 2) {
+ List leftSubTree = dfs(left);
+ List rightSubTree = dfs(n - 1 - left);
+ for (TreeNode l : leftSubTree) {
+ for (TreeNode r : rightSubTree) {
+ res.add(new TreeNode(0, l, r));
+ }
+ }
+ }
+
+ return dp[n] = res;
+ }
+}
+```
+
+```cpp
+/**
+ * Definition for a binary tree node.
+ * struct TreeNode {
+ * int val;
+ * TreeNode *left;
+ * TreeNode *right;
+ * TreeNode() : val(0), left(nullptr), right(nullptr) {}
+ * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
+ * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
+ * };
+ */
+class Solution {
+private:
+ vector> dp;
+
+public:
+ vector allPossibleFBT(int n) {
+ dp.resize(n + 1);
+ return dfs(n);
+ }
+
+ vector dfs(int n) {
+ if (n % 2 == 0) {
+ return {};
+ }
+ if (n == 1) {
+ return {new TreeNode(0)};
+ }
+ if (!dp[n].empty()) {
+ return dp[n];
+ }
+
+ vector res;
+ for (int left = 1; left < n; left += 2) {
+ vector leftSubTree = dfs(left);
+ vector rightSubTree = dfs(n - 1 - left);
+ for (auto& l : leftSubTree) {
+ for (auto& r : rightSubTree) {
+ res.push_back(new TreeNode(0, l, r));
+ }
+ }
+ }
+
+ return dp[n] = res;
+ }
+};
+```
+
+```javascript
+/**
+ * Definition for a binary tree node.
+ * class TreeNode {
+ * constructor(val = 0, left = null, right = null) {
+ * this.val = val;
+ * this.left = left;
+ * this.right = right;
+ * }
+ * }
+ */
+class Solution {
+ /**
+ * @param {number} n
+ * @return {TreeNode[]}
+ */
+ allPossibleFBT(n) {
+ let dp = new Array(n + 1);
+
+ const dfs = (n) => {
+ if (n % 2 === 0) {
+ return [];
+ }
+ if (n === 1) {
+ return [new TreeNode(0)];
+ }
+ if (dp[n]) {
+ return dp[n];
+ }
+
+ let res = [];
+ for (let left = 1; left < n; left += 2) {
+ let leftSubTree = dfs(left);
+ let rightSubTree = dfs(n - 1 - left);
+ for (let t1 of leftSubTree) {
+ for (let t2 of rightSubTree) {
+ res.push(new TreeNode(0, t1, t2));
+ }
+ }
+ }
+
+ return (dp[n] = res);
+ };
+
+ return dfs(n);
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(2 ^ n)$
+* Space complexity: $O(n * 2 ^ n)$
+
+---
+
+## 4. Dynamic Programming (Bottom-Up)
+
+::tabs-start
+
+```python
+# Definition for a binary tree node.
+# class TreeNode:
+# def __init__(self, val=0, left=None, right=None):
+# self.val = val
+# self.left = left
+# self.right = right
+class Solution:
+ def allPossibleFBT(self, n: int) -> List[Optional[TreeNode]]:
+ if n % 2 == 0:
+ return []
+
+ dp = [[] for _ in range(n + 1)]
+ dp[1] = [TreeNode(0)]
+
+ for nodes in range(3, n + 1, 2):
+ res = []
+ for left in range(1, nodes, 2):
+ right = nodes - 1 - left
+ for t1 in dp[left]:
+ for t2 in dp[right]:
+ res.append(TreeNode(0, t1, t2))
+ dp[nodes] = res
+
+ return dp[n]
+```
+
+```java
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * int val;
+ * TreeNode left;
+ * TreeNode right;
+ * TreeNode() {}
+ * TreeNode(int val) { this.val = val; }
+ * TreeNode(int val, TreeNode left, TreeNode right) {
+ * this.val = val;
+ * this.left = left;
+ * this.right = right;
+ * }
+ * }
+ */
+public class Solution {
+ public List allPossibleFBT(int n) {
+ if (n % 2 == 0) {
+ return new ArrayList<>();
+ }
+
+ List[] dp = new ArrayList[n + 1];
+ for (int i = 0; i <= n; i++) {
+ dp[i] = new ArrayList<>();
+ }
+ dp[1].add(new TreeNode(0));
+
+ for (int nodes = 3; nodes <= n; nodes += 2) {
+ List res = new ArrayList<>();
+ for (int left = 1; left < nodes; left += 2) {
+ int right = nodes - 1 - left;
+ for (TreeNode t1 : dp[left]) {
+ for (TreeNode t2 : dp[right]) {
+ res.add(new TreeNode(0, t1, t2));
+ }
+ }
+ }
+ dp[nodes] = res;
+ }
+
+ return dp[n];
+ }
+}
+```
+
+```cpp
+/**
+ * Definition for a binary tree node.
+ * struct TreeNode {
+ * int val;
+ * TreeNode *left;
+ * TreeNode *right;
+ * TreeNode() : val(0), left(nullptr), right(nullptr) {}
+ * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
+ * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
+ * };
+ */
+class Solution {
+public:
+ vector allPossibleFBT(int n) {
+ if (n % 2 == 0) {
+ return {};
+ }
+
+ vector> dp(n + 1);
+ dp[1].push_back(new TreeNode(0));
+
+ for (int nodes = 3; nodes <= n; nodes += 2) {
+ vector res;
+ for (int left = 1; left < nodes; left += 2) {
+ int right = nodes - 1 - left;
+ for (auto& t1 : dp[left]) {
+ for (auto& t2 : dp[right]) {
+ res.push_back(new TreeNode(0, t1, t2));
+ }
+ }
+ }
+ dp[nodes] = res;
+ }
+
+ return dp[n];
+ }
+};
+```
+
+```javascript
+/**
+ * Definition for a binary tree node.
+ * class TreeNode {
+ * constructor(val = 0, left = null, right = null) {
+ * this.val = val;
+ * this.left = left;
+ * this.right = right;
+ * }
+ * }
+ */
+class Solution {
+ /**
+ * @param {number} n
+ * @return {TreeNode[]}
+ */
+ allPossibleFBT(n) {
+ if (n % 2 === 0) {
+ return [];
+ }
+
+ let dp = Array.from({ length: n + 1 }, () => []);
+ dp[1] = [new TreeNode(0)];
+
+ for (let nodes = 3; nodes <= n; nodes += 2) {
+ let res = [];
+ for (let left = 1; left < nodes; left += 2) {
+ let right = nodes - 1 - left;
+ for (let t1 of dp[left]) {
+ for (let t2 of dp[right]) {
+ res.push(new TreeNode(0, t1, t2));
+ }
+ }
+ }
+ dp[nodes] = res;
+ }
+
+ return dp[n];
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(2 ^ n)$
+* Space complexity: $O(n * 2 ^ n)$
\ 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/analyze-user-website-visit-pattern.md b/articles/analyze-user-website-visit-pattern.md
new file mode 100644
index 000000000..c43fce6ba
--- /dev/null
+++ b/articles/analyze-user-website-visit-pattern.md
@@ -0,0 +1,224 @@
+## 1. Hash Map
+
+::tabs-start
+
+```python
+class Solution:
+ def mostVisitedPattern(self, username: List[str], timestamp: List[int], website: List[str]) -> List[str]:
+ arr = list(zip(timestamp, username, website))
+ arr.sort()
+
+ mp = defaultdict(list)
+ for time, user, site in arr:
+ mp[user].append(site)
+
+ count = defaultdict(int)
+ for user in mp:
+ patterns = set()
+ cur = mp[user]
+ for i in range(len(cur)):
+ for j in range(i + 1, len(cur)):
+ for k in range(j + 1, len(cur)):
+ patterns.add((cur[i], cur[j], cur[k]))
+ for p in patterns:
+ count[p] += 1
+
+ max_count = 0
+ res = tuple()
+ for pattern in count:
+ if count[pattern] > max_count or (count[pattern] == max_count and pattern < res):
+ max_count = count[pattern]
+ res = pattern
+
+ return list(res)
+```
+
+```java
+public class Solution {
+ public List mostVisitedPattern(String[] username, int[] timestamp, String[] website) {
+ int n = timestamp.length;
+ List arr = new ArrayList<>();
+ for (int i = 0; i < n; i++) arr.add(new int[]{timestamp[i], i});
+ arr.sort((a, b) -> Integer.compare(a[0], b[0]));
+
+ Map> mp = new HashMap<>();
+ for (int[] p : arr) {
+ int idx = p[1];
+ mp.computeIfAbsent(username[idx], k -> new ArrayList<>()).add(website[idx]);
+ }
+
+ Map count = new HashMap<>();
+ for (String user : mp.keySet()) {
+ List cur = mp.get(user);
+ Set patterns = new HashSet<>();
+ for (int i = 0; i < cur.size(); i++)
+ for (int j = i + 1; j < cur.size(); j++)
+ for (int k = j + 1; k < cur.size(); k++)
+ patterns.add(cur.get(i) + "#" + cur.get(j) + "#" + cur.get(k));
+ for (String p : patterns)
+ count.put(p, count.getOrDefault(p, 0) + 1);
+ }
+
+ String res = "";
+ int max_count = 0;
+ for (String p : count.keySet()) {
+ int c = count.get(p);
+ if (c > max_count || (c == max_count && p.compareTo(res) < 0)) {
+ max_count = c;
+ res = p;
+ }
+ }
+ return Arrays.asList(res.split("#"));
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ vector mostVisitedPattern(vector& username, vector& timestamp, vector& website) {
+ int n = timestamp.size();
+ vector> arr;
+ for (int i = 0; i < n; ++i) arr.push_back({timestamp[i], i});
+ sort(arr.begin(), arr.end(),
+ [](auto& a, auto& b){ return a.first < b.first; });
+
+ unordered_map> mp;
+ for (auto& p : arr) mp[username[p.second]].push_back(website[p.second]);
+
+ unordered_map count;
+ for (auto& kv : mp) {
+ auto& cur = kv.second;
+ unordered_set patterns;
+ for (int i = 0; i < (int)cur.size(); ++i)
+ for (int j = i + 1; j < (int)cur.size(); ++j)
+ for (int k = j + 1; k < (int)cur.size(); ++k)
+ patterns.insert(cur[i] + "#" + cur[j] + "#" + cur[k]);
+ for (auto& p : patterns) ++count[p];
+ }
+
+ int maxCnt = 0;
+ string res;
+ for (auto& kv : count)
+ if (kv.second > maxCnt ||
+ (kv.second == maxCnt && (res.empty() || kv.first < res))) {
+ maxCnt = kv.second;
+ res = kv.first;
+ }
+
+ vector ans;
+ string tmp;
+ for (char ch : res) {
+ if (ch == '#') {
+ ans.push_back(tmp);
+ tmp.clear();
+ } else {
+ tmp += ch;
+ }
+ }
+ ans.push_back(tmp);
+ return ans;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {string[]} username
+ * @param {number[]} timestamp
+ * @param {string[]} website
+ * @return {string[]}
+ */
+ mostVisitedPattern(username, timestamp, website) {
+ const n = timestamp.length;
+ const arr = [];
+ for (let i = 0; i < n; i++) arr.push([timestamp[i], i]);
+ arr.sort((a, b) => a[0] - b[0]);
+
+ const mp = new Map();
+ for (const [, idx] of arr) {
+ const user = username[idx], site = website[idx];
+ if (!mp.has(user)) mp.set(user, []);
+ mp.get(user).push(site);
+ }
+
+ const count = new Map();
+ for (const user of mp.keys()) {
+ const cur = mp.get(user);
+ const patterns = new Set();
+ for (let i = 0; i < cur.length; i++) {
+ for (let j = i + 1; j < cur.length; j++) {
+ for (let k = j + 1; k < cur.length; k++) {
+ patterns.add(`${cur[i]}#${cur[j]}#${cur[k]}`);
+ }
+ }
+ }
+ for (const p of patterns) {
+ count.set(p, (count.get(p) || 0) + 1);
+ }
+ }
+
+ let maxCnt = 0, res = "";
+ for (const [pat, c] of count.entries()) {
+ if (c > maxCnt || (c === maxCnt && (res === "" || pat < res))) {
+ maxCnt = c;
+ res = pat;
+ }
+ }
+ return res.split("#");
+ }
+}
+```
+
+```csharp
+public class Solution {
+ public List MostVisitedPattern(string[] username, int[] timestamp, string[] website) {
+ int n = timestamp.Length;
+ var arr = new List<(int t, int i)>();
+ for (int i = 0; i < n; i++) arr.Add((timestamp[i], i));
+ arr.Sort((a, b) => a.t.CompareTo(b.t));
+
+ var mp = new Dictionary>();
+ foreach (var (t, idx) in arr) {
+ string user = username[idx], site = website[idx];
+ if (!mp.ContainsKey(user)) mp[user] = new List();
+ mp[user].Add(site);
+ }
+
+ var count = new Dictionary();
+ foreach (var kv in mp) {
+ var cur = kv.Value;
+ var patterns = new HashSet();
+ for (int i = 0; i < cur.Count; i++)
+ for (int j = i + 1; j < cur.Count; j++)
+ for (int k = j + 1; k < cur.Count; k++)
+ patterns.Add($"{cur[i]}#{cur[j]}#{cur[k]}");
+ foreach (var p in patterns) {
+ count[p] = count.ContainsKey(p) ? count[p] + 1 : 1;
+ }
+ }
+
+ int maxCnt = 0;
+ string res = "";
+ foreach (var kv in count) {
+ if (kv.Value > maxCnt ||
+ (kv.Value == maxCnt &&
+ (res == "" || string.Compare(kv.Key, res, StringComparison.Ordinal) < 0))) {
+ maxCnt = kv.Value;
+ res = kv.Key;
+ }
+ }
+ return new List(res.Split('#'));
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n \log n + n * u + n ^ 3 * w)$
+* Space complexity: $O(n * u + n ^ 3 * w)$
+
+> Where $n$ is the size of the array $timestamp$, $u$ is the maximum length of any string in the array $username$, and $w$ is the maximum length of any string in the array $website$.
\ No newline at end of file
diff --git a/articles/append-characters-to-string-to-make-subsequence.md b/articles/append-characters-to-string-to-make-subsequence.md
new file mode 100644
index 000000000..de5f09613
--- /dev/null
+++ b/articles/append-characters-to-string-to-make-subsequence.md
@@ -0,0 +1,210 @@
+## 1. Two Pointers
+
+::tabs-start
+
+```python
+class Solution:
+ def appendCharacters(self, s: str, t: str) -> int:
+ i, j = 0, 0
+
+ while i < len(s) and j < len(t):
+ if s[i] == t[j]:
+ i += 1
+ j += 1
+ else:
+ i += 1
+ return len(t) - j
+```
+
+```java
+public class Solution {
+ public int appendCharacters(String s, String t) {
+ int i = 0, j = 0;
+
+ while (i < s.length() && j < t.length()) {
+ if (s.charAt(i) == t.charAt(j)) {
+ i++;
+ j++;
+ } else {
+ i++;
+ }
+ }
+ return t.length() - j;
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ int appendCharacters(string s, string t) {
+ int i = 0, j = 0;
+
+ while (i < s.length() && j < t.length()) {
+ if (s[i] == t[j]) {
+ i++;
+ j++;
+ } else {
+ i++;
+ }
+ }
+ return t.length() - j;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {string} s
+ * @param {string} t
+ * @return {number}
+ */
+ appendCharacters(s, t) {
+ let i = 0, j = 0;
+
+ while (i < s.length && j < t.length) {
+ if (s[i] === t[j]) {
+ i++;
+ j++;
+ } else {
+ i++;
+ }
+ }
+ return t.length - j;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n + m)$
+* Space complexity: $O(1)$
+
+> Where $n$ and $m$ are the lengths of the strings $s$ and $t$, respectively.
+
+---
+
+## 2. Index Jumping
+
+::tabs-start
+
+```python
+class Solution:
+ def appendCharacters(self, s: str, t: str) -> int:
+ n, m = len(s), len(t)
+ store = [[n + 1] * 26 for _ in range(n)]
+ store[n - 1][ord(s[n - 1]) - ord('a')] = n - 1
+
+ for i in range(n - 2, -1, -1):
+ store[i] = store[i + 1][:]
+ store[i][ord(s[i]) - ord('a')] = i
+
+ i, j = 0, 0
+ while i < n and j < m:
+ if store[i][ord(t[j]) - ord('a')] == n + 1:
+ break
+
+ i = store[i][ord(t[j]) - ord('a')] + 1
+ j += 1
+
+ return m - j
+```
+
+```java
+public class Solution {
+ public int appendCharacters(String s, String t) {
+ int n = s.length(), m = t.length();
+ int[][] store = new int[n][26];
+ for (int[] row : store) {
+ Arrays.fill(row, n + 1);
+ }
+ store[n - 1][s.charAt(n - 1) - 'a'] = n - 1;
+
+ for (int i = n - 2; i >= 0; i--) {
+ store[i] = store[i + 1].clone();
+ store[i][s.charAt(i) - 'a'] = i;
+ }
+
+ int i = 0, j = 0;
+ while (i < n && j < m) {
+ if (store[i][t.charAt(j) - 'a'] == n + 1) {
+ break;
+ }
+ i = store[i][t.charAt(j) - 'a'] + 1;
+ j++;
+ }
+
+ return m - j;
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ int appendCharacters(string s, string t) {
+ int n = s.length(), m = t.length();
+ vector> store(n, vector(26, n + 1));
+ store[n - 1][s[n - 1] - 'a'] = n - 1;
+
+ for (int i = n - 2; i >= 0; i--) {
+ store[i] = store[i + 1];
+ store[i][s[i] - 'a'] = i;
+ }
+
+ int i = 0, j = 0;
+ while (i < n && j < m) {
+ if (store[i][t[j] - 'a'] == n + 1) {
+ break;
+ }
+ i = store[i][t[j] - 'a'] + 1;
+ j++;
+ }
+
+ return m - j;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {string} s
+ * @param {string} t
+ * @return {number}
+ */
+ appendCharacters(s, t) {
+ const n = s.length, m = t.length;
+ const store = Array.from({ length: n }, () => Array(26).fill(n + 1));
+ store[n - 1][s.charCodeAt(n - 1) - 97] = n - 1;
+
+ for (let i = n - 2; i >= 0; i--) {
+ store[i] = store[i + 1].slice();
+ store[i][s.charCodeAt(i) - 97] = i;
+ }
+
+ let i = 0, j = 0;
+ while (i < n && j < m) {
+ if (store[i][t.charCodeAt(j) - 97] === n + 1) {
+ break;
+ }
+ i = store[i][t.charCodeAt(j) - 97] + 1;
+ j++;
+ }
+
+ return m - j;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n + m)$
+* Space complexity: $O(n)$
+
+> Where $n$ and $m$ are the lengths of the strings $s$ and $t$, respectively.
\ No newline at end of file
diff --git a/articles/arithmetic-slices-ii-subsequence.md b/articles/arithmetic-slices-ii-subsequence.md
new file mode 100644
index 000000000..427b1557c
--- /dev/null
+++ b/articles/arithmetic-slices-ii-subsequence.md
@@ -0,0 +1,499 @@
+## 1. Brute Force
+
+::tabs-start
+
+```python
+class Solution:
+ def numberOfArithmeticSlices(self, nums: List[int]) -> int:
+ n = len(nums)
+ if n < 3:
+ return 0
+
+ INF = float('inf')
+ dp = {}
+
+ def dfs(i, j, diff, flag):
+ if i == n:
+ return flag
+ if (i, j, diff, flag) in dp:
+ return dp[(i, j, diff, flag)]
+
+ res = dfs(i + 1, j, diff, flag)
+ if j == -1:
+ res += dfs(i + 1, i, INF, flag)
+ else:
+ if diff == INF:
+ res += dfs(i + 1, i, nums[i] - nums[j], flag)
+ elif diff == nums[i] - nums[j]:
+ res += dfs(i + 1, i, diff, 1)
+
+ dp[(i, j, diff, flag)] = res
+ return res
+
+ return dfs(0, -1, INF, 0)
+```
+
+```java
+public class Solution {
+ private static final long INF = (long) 1e15;
+ private Map dp = new HashMap<>();
+
+ public int numberOfArithmeticSlices(int[] nums) {
+ int n = nums.length;
+ if (n < 3) return 0;
+
+ return dfs(nums, 0, -1, INF, 0);
+ }
+
+ private int dfs(int[] nums, int i, int j, long diff, int flag) {
+ if (i == nums.length) {
+ return flag;
+ }
+ String key = i + "," + j + "," + diff + "," + flag;
+ if (dp.containsKey(key)) {
+ return dp.get(key);
+ }
+
+ int res = dfs(nums, i + 1, j, diff, flag);
+ if (j == -1) {
+ res += dfs(nums, i + 1, i, INF, flag);
+ } else {
+ if (diff == INF) {
+ res += dfs(nums, i + 1, i, nums[i] - 0L - nums[j], flag);
+ } else if (diff == nums[i] - 0L - nums[j]) {
+ res += dfs(nums, i + 1, i, diff, 1);
+ }
+ }
+
+ dp.put(key, res);
+ return res;
+ }
+}
+```
+
+```cpp
+class Solution {
+ static const long long INF = 1e15;
+ unordered_map dp;
+
+ int dfs(vector& nums, int i, int j, long long diff, int flag) {
+ if (i == nums.size()) {
+ return flag;
+ }
+
+ string key = to_string(i) + "," + to_string(j) + "," + to_string(diff) + "," + to_string(flag);
+ if (dp.count(key)) {
+ return dp[key];
+ }
+
+ int res = dfs(nums, i + 1, j, diff, flag);
+ if (j == -1) {
+ res += dfs(nums, i + 1, i, INF, flag);
+ } else {
+ if (diff == INF) {
+ res += dfs(nums, i + 1, i, nums[i] - 0LL - nums[j], flag);
+ } else if (diff == nums[i] - 0LL - nums[j]) {
+ res += dfs(nums, i + 1, i, diff, 1);
+ }
+ }
+
+ dp[key] = res;
+ return res;
+ }
+
+public:
+ int numberOfArithmeticSlices(vector& nums) {
+ if (nums.size() < 3) return 0;
+ return dfs(nums, 0, -1, INF, 0);
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} nums
+ * @return {number}
+ */
+ numberOfArithmeticSlices(nums) {
+ const n = nums.length;
+ if (n < 3) return 0;
+
+ const INF = Infinity;
+ const dp = new Map();
+
+ const dfs = (i, j, diff, flag) => {
+ if (i === n) {
+ return flag;
+ }
+ const key = `${i},${j},${diff},${flag}`;
+ if (dp.has(key)) {
+ return dp.get(key);
+ }
+
+ let res = dfs(i + 1, j, diff, flag);
+ if (j === -1) {
+ res += dfs(i + 1, i, INF, flag);
+ } else {
+ if (diff === INF) {
+ res += dfs(i + 1, i, nums[i] - nums[j], flag);
+ } else if (diff === nums[i] - nums[j]) {
+ res += dfs(i + 1, i, diff, 1);
+ }
+ }
+
+ dp.set(key, res);
+ return res;
+ };
+
+ return dfs(0, -1, INF, 0);
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n ^ 3)$
+* Space complexity: $O(n ^ 3)$
+
+---
+
+## 2. Dynamic Programming (Bottom-Up)
+
+::tabs-start
+
+```python
+class Solution:
+ def numberOfArithmeticSlices(self, nums: List[int]) -> int:
+ res, n = 0, len(nums)
+ dp = [defaultdict(int) for _ in range(n)]
+
+ for i in range(n):
+ for j in range(i):
+ diff = nums[i] - nums[j]
+ dp[i][diff] += 1 + dp[j][diff]
+ res += dp[j][diff]
+
+ return res
+```
+
+```java
+public class Solution {
+ public int numberOfArithmeticSlices(int[] nums) {
+ int n = nums.length;
+ int res = 0;
+ Map[] dp = new HashMap[n];
+
+ for (int i = 0; i < n; i++) {
+ dp[i] = new HashMap<>();
+ for (int j = 0; j < i; j++) {
+ long diff = (long) nums[i] - nums[j];
+ int count = dp[j].getOrDefault(diff, 0);
+ dp[i].put(diff, dp[i].getOrDefault(diff, 0) + count + 1);
+ res += count;
+ }
+ }
+ return res;
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ int numberOfArithmeticSlices(vector& nums) {
+ int n = nums.size();
+ int res = 0;
+ vector> dp(n);
+
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < i; j++) {
+ long long diff = (long long) nums[i] - nums[j];
+ int count = dp[j][diff];
+ dp[i][diff] += count + 1;
+ res += count;
+ }
+ }
+ return res;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} nums
+ * @return {number}
+ */
+ numberOfArithmeticSlices(nums) {
+ const n = nums.length;
+ let res = 0;
+ const dp = Array.from({ length: n }, () => new Map());
+
+ for (let i = 0; i < n; i++) {
+ for (let j = 0; j < i; j++) {
+ const diff = nums[i] - nums[j];
+ const count = dp[j].get(diff) || 0;
+ dp[i].set(diff, (dp[i].get(diff) || 0) + count + 1);
+ res += count;
+ }
+ }
+ return res;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n ^ 2)$
+* Space complexity: $O(n ^ 2)$
+
+---
+
+## 3. Dynamic Programming (Optimization) - I
+
+::tabs-start
+
+```python
+class Solution:
+ def numberOfArithmeticSlices(self, nums: List[int]) -> int:
+ res, n = 0, len(nums)
+ s = set(nums)
+ dp = [defaultdict(int) for _ in range(n)]
+
+ for i in range(n):
+ for j in range(i):
+ diff = nums[i] - nums[j]
+ cnt = dp[j].get(diff, 0)
+ if nums[i] + diff in s:
+ dp[i][diff] += cnt + 1
+ res += cnt
+
+ return res
+```
+
+```java
+public class Solution {
+ public int numberOfArithmeticSlices(int[] nums) {
+ int res = 0, n = nums.length;
+ Set s = new HashSet<>();
+ for (int num : nums) s.add(num);
+
+ Map[] dp = new HashMap[n];
+ for (int i = 0; i < n; i++) dp[i] = new HashMap<>();
+
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < i; j++) {
+ long diff = (long) nums[i] - nums[j];
+ int cnt = dp[j].getOrDefault(diff, 0);
+ if (s.contains((int) (nums[i] + diff))) {
+ dp[i].put(diff, dp[i].getOrDefault(diff, 0) + cnt + 1);
+ }
+ res += cnt;
+ }
+ }
+ return res;
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ int numberOfArithmeticSlices(vector& nums) {
+ int res = 0, n = nums.size();
+ unordered_set s(nums.begin(), nums.end());
+ vector> dp(n);
+
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < i; j++) {
+ long long diff = (long long)nums[i] - nums[j];
+ int cnt = dp[j].count(diff) ? dp[j][diff] : 0;
+ if (s.count(nums[i] + diff)) {
+ dp[i][diff] += cnt + 1;
+ }
+ res += cnt;
+ }
+ }
+ return res;
+ }
+};
+```
+
+```javascript
+class Solution {
+ /**
+ * @param {number[]} nums
+ * @return {number}
+ */
+ numberOfArithmeticSlices(nums) {
+ let res = 0, n = nums.length;
+ const s = new Set(nums);
+ const dp = Array.from({ length: n }, () => new Map());
+
+ for (let i = 0; i < n; i++) {
+ for (let j = 0; j < i; j++) {
+ const diff = nums[i] - nums[j];
+ const cnt = dp[j].get(diff) || 0;
+ if (s.has(nums[i] + diff)) {
+ dp[i].set(diff, (dp[i].get(diff) || 0) + cnt + 1);
+ }
+ res += cnt;
+ }
+ }
+ return res;
+ }
+}
+```
+
+::tabs-end
+
+### Time & Space Complexity
+
+* Time complexity: $O(n ^ 2)$
+* Space complexity: $O(n ^ 2)$
+
+---
+
+## 4. Dynamic Programming (Optimization) - II
+
+::tabs-start
+
+```python
+class Solution:
+ def numberOfArithmeticSlices(self, nums: List[int]) -> int:
+ res = 0
+ mpIdx = defaultdict(list)
+ n = len(nums)
+ dp = [[0] * n for _ in range(n)]
+
+ for i in range(n):
+ mpIdx[nums[i]].append(i)
+
+ for i in range(n):
+ for j in range(i):
+ prev = 2 * nums[j] - nums[i]
+ if prev in mpIdx:
+ for k in mpIdx[prev]:
+ if k >= j:
+ break
+ dp[i][j] += dp[j][k] + 1
+ res += dp[i][j]
+
+ return res
+```
+
+```java
+public class Solution {
+ public int numberOfArithmeticSlices(int[] nums) {
+ int res = 0;
+ Map> mpIdx = new HashMap<>();
+ int n = nums.length;
+ int[][] dp = new int[n][n];
+
+ for (int i = 0; i < n; i++) {
+ mpIdx.putIfAbsent(nums[i], new ArrayList<>());
+ mpIdx.get(nums[i]).add(i);
+ }
+
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < i; j++) {
+ long prev = 2L * nums[j] - nums[i];
+ if (prev < Integer.MIN_VALUE || prev > Integer.MAX_VALUE) {
+ continue;
+ }
+
+ if (mpIdx.containsKey((int) prev)) {
+ for (int k : mpIdx.get((int) prev)) {
+ if (k >= j) break;
+ dp[i][j] += dp[j][k] + 1;
+ }
+ }
+ res += dp[i][j];
+ }
+ }
+
+ return res;
+ }
+}
+```
+
+```cpp
+class Solution {
+public:
+ int numberOfArithmeticSlices(vector& nums) {
+ int res = 0;
+ unordered_map