Skip to content

Commit c538d48

Browse files
fornmatter
1 parent d0a5256 commit c538d48

File tree

369 files changed

+1926
-1975
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

369 files changed

+1926
-1975
lines changed

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
npm run format:json
2+
npm run format:python

explanations/57/en.md

Lines changed: 39 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,61 @@
1-
You are given an array of non-overlapping intervals `intervals` where `intervals[i] = [start_i, end_i]` represent the start and the end of the `i^th` interval and `intervals` is sorted in ascending order by `start_i`. You are also given an interval `newInterval = [start, end]` that represents the start and end of another interval.
2-
3-
Insert `newInterval` into `intervals` such that `intervals` is still sorted in ascending order by `start_i` and `intervals` still does not have any overlapping intervals (merge overlapping intervals if necessary).
4-
5-
Return `intervals` *after the insertion*.
6-
7-
**Note** that you don't need to modify `intervals` in-place. You can make a new array and return it.
8-
9-
**Example 1:**
10-
11-
```sh
12-
Input: intervals = [[1,3],[6,9]], newInterval = [2,5]
13-
Output: [[1,5],[6,9]]
14-
```
15-
16-
**Example 2:**
17-
18-
```sh
19-
Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
20-
Output: [[1,2],[3,10],[12,16]]
21-
Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].
22-
```
23-
24-
**Constraints:**
1+
## Explanation
252

26-
- `0 <= intervals.length <= 10^4`
27-
- `intervals[i].length == 2`
28-
- `0 <= start_i <= end_i <= 10^5`
29-
- `intervals` is sorted by `start_i` in **ascending** order.
30-
- `newInterval.length == 2`
31-
- `0 <= start <= end <= 10^5`
3+
### Strategy (The "Why")
324

33-
## Explanation
5+
**Restate the problem:** We are given a sorted array of non-overlapping intervals and a new interval. We need to insert the new interval into the array such that the result remains sorted and all overlapping intervals are merged.
346

35-
### Strategy
7+
**1.1 Constraints & Complexity:**
368

37-
This is an **array manipulation problem** that requires inserting a new interval into a sorted list of non-overlapping intervals. The key insight is to process intervals in three phases: before overlap, during overlap, and after overlap.
9+
- **Input Size:** Up to 10^4 intervals, each with start and end values up to 10^5.
10+
- **Time Complexity:** O(n) where n is the number of intervals. We traverse the array once, processing each interval at most once.
11+
- **Space Complexity:** O(n) to store the result array.
12+
- **Edge Case:** If the intervals array is empty, we return an array containing only the new interval.
3813

39-
**Key observations:**
40-
- Intervals are already sorted by start time
41-
- We need to find where the new interval fits
42-
- We may need to merge multiple overlapping intervals
43-
- Process intervals in three phases based on overlap with new interval
14+
**1.2 High-level approach:**
4415

45-
**High-level approach:**
46-
1. **Add intervals before overlap**: Add all intervals that end before new interval starts
47-
2. **Merge overlapping intervals**: Find all intervals that overlap with new interval
48-
3. **Add merged interval**: Add the final merged interval
49-
4. **Add remaining intervals**: Add all intervals that start after new interval ends
16+
The goal is to process intervals in three phases: add intervals that come before the new interval, merge all intervals that overlap with the new interval, and add the remaining intervals that come after.
5017

51-
### Steps
18+
**1.3 Brute force vs. optimized strategy:**
5219

53-
Let's break down the solution step by step:
20+
- **Brute Force:** Insert the new interval, sort the entire array, then merge overlapping intervals. This would be O(n log n) time due to sorting.
21+
- **Optimized Strategy:** Since intervals are already sorted, we can process them in a single pass: add intervals before overlap, merge overlapping ones, then add remaining intervals. This is O(n) time.
22+
- **Optimization:** By leveraging the fact that intervals are already sorted, we avoid the need for sorting and can process everything in one pass, making the solution more efficient.
5423

55-
**Step 1: Initialize result list**
56-
- Create empty result list: `result = []`
24+
**1.4 Decomposition:**
5725

58-
**Step 2: Add intervals before overlap**
59-
- Add all intervals where `interval[1] < newInterval[0]`
26+
1. Add all intervals that end before the new interval starts (no overlap).
27+
2. Merge all intervals that overlap with the new interval by updating the start and end boundaries.
28+
3. Add the merged interval to the result.
29+
4. Add all remaining intervals that start after the merged interval ends.
6030

61-
**Step 3: Merge overlapping intervals**
62-
- Find all intervals that overlap with new interval
63-
- Update new interval boundaries: `start = min(start, interval[0])`, `end = max(end, interval[1])`
31+
### Steps (The "How")
6432

65-
**Step 4: Add merged interval**
66-
- Add the final merged interval to result
33+
**2.1 Initialization & Example Setup:**
6734

68-
**Step 5: Add remaining intervals**
69-
- Add all intervals where `interval[0] > newInterval[1]`
35+
Let's use the example: `intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]]`, `newInterval = [4,8]`
7036

71-
**Example walkthrough:**
72-
Let's trace through the second example:
37+
- Result array: `res = []`
38+
- Index `i = 0`
39+
- New interval boundaries: `start = 4`, `end = 8`
7340

74-
```sh
75-
intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
41+
**2.2 Start Processing:**
7642

77-
Step 1: Add intervals before overlap
78-
result = [[1,2]] (3,5 overlaps, so stop)
43+
We begin processing intervals from left to right, checking each interval's relationship with the new interval.
7944

80-
Step 2: Merge overlapping intervals
81-
Overlap with [3,5]: newInterval = [min(4,3), max(8,5)] = [3,8]
82-
Overlap with [6,7]: newInterval = [min(3,6), max(8,7)] = [3,8]
83-
Overlap with [8,10]: newInterval = [min(3,8), max(8,10)] = [3,10]
45+
**2.3 Trace Walkthrough:**
8446

85-
Step 3: Add merged interval
86-
result = [[1,2],[3,10]]
47+
| Step | i | Interval | Condition | Action | res | start, end |
48+
| ---- | - | -------- | --------- | ------ | --- | ---------- |
49+
| 1 | 0 | [1,2] | 2 < 4 (ends before) | Add to res | `[[1,2]]` | 4, 8 |
50+
| 2 | 1 | [3,5] | 3 <= 8 (overlaps) | Merge: start=min(4,3)=3, end=max(8,5)=8 | `[[1,2]]` | 3, 8 |
51+
| 3 | 2 | [6,7] | 6 <= 8 (overlaps) | Merge: start=min(3,6)=3, end=max(8,7)=8 | `[[1,2]]` | 3, 8 |
52+
| 4 | 3 | [8,10] | 8 <= 8 (overlaps) | Merge: start=min(3,8)=3, end=max(8,10)=10 | `[[1,2]]` | 3, 10 |
53+
| 5 | 4 | [12,16] | 12 > 10 (starts after) | Add merged [3,10], then add [12,16] | `[[1,2],[3,10],[12,16]]` | - |
8754

88-
Step 4: Add remaining intervals
89-
result = [[1,2],[3,10],[12,16]]
55+
**2.4 Increment and Loop:**
9056

91-
Result: [[1,2],[3,10],[12,16]]
92-
```
57+
After processing each interval, we increment the index `i` and continue until all intervals are processed.
9358

94-
> **Note:** The key insight is to process intervals in three phases. This approach is efficient because we only need to traverse the array once, and we can determine which phase each interval belongs to by comparing its boundaries with the new interval.
59+
**2.5 Return Result:**
9560

96-
**Time Complexity:** O(n) - we visit each interval at most once
97-
**Space Complexity:** O(n) - to store the result
61+
The result is `[[1,2],[3,10],[12,16]]`, where the new interval [4,8] has been merged with overlapping intervals [3,5], [6,7], and [8,10] to form [3,10].

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"scripts": {
33
"format:json": "prettier --write 'data/**/*.json'",
4+
"format:python": "black scripts/ solutions/",
45
"prepare": "husky"
56
},
67
"devDependencies": {

requirements.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
2-
1+
black>=24.0.0

scripts/update_problems_from_leetcode.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,7 @@ def map_tags_to_category(tags: List[Dict[str, str]]) -> str:
102102
elif any("greedy" in t for t in all_tags):
103103
return "Greedy"
104104
elif any(
105-
"math" in t
106-
or "geometry" in t
107-
or "number-theory" in t
108-
or "combinatorics" in t
105+
"math" in t or "geometry" in t or "number-theory" in t or "combinatorics" in t
109106
for t in all_tags
110107
):
111108
return "Math & Geometry"
@@ -324,4 +321,3 @@ def main():
324321

325322
if __name__ == "__main__":
326323
main()
327-

solutions/100/01.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@ def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
99
# Both are None
1010
if not p and not q:
1111
return True
12-
12+
1313
# One is None, the other is not
1414
if not p or not q:
1515
return False
16-
16+
1717
# Both exist, check values and recursively check children
1818
if p.val != q.val:
1919
return False
20-
21-
return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
2220

21+
return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)

solutions/1004/01.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
from typing import List
22

3+
34
class Solution:
45
def longestOnes(self, nums: List[int], k: int) -> int:
56
left = 0
67
max_length = 0
78
zero_count = 0
8-
9+
910
for right in range(len(nums)):
1011
# Expand window
1112
if nums[right] == 0:
1213
zero_count += 1
13-
14+
1415
# Shrink window if zero_count exceeds k
1516
while zero_count > k:
1617
if nums[left] == 0:
1718
zero_count -= 1
1819
left += 1
19-
20+
2021
# Update maximum length
2122
max_length = max(max_length, right - left + 1)
22-
23+
2324
return max_length

solutions/1008/01.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ class Solution:
88
def bstFromPreorder(self, preorder: List[int]) -> Optional[TreeNode]:
99
if not preorder:
1010
return None
11-
11+
1212
root = TreeNode(preorder[0])
13-
13+
1414
# Find the split point where values become greater than root
1515
i = 1
1616
while i < len(preorder) and preorder[i] < preorder[0]:
1717
i += 1
18-
18+
1919
root.left = self.bstFromPreorder(preorder[1:i])
2020
root.right = self.bstFromPreorder(preorder[i:])
21-
21+
2222
return root

solutions/101/01.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,21 @@
55
# self.left = left
66
# self.right = right
77

8+
89
class Solution:
910
def isSymmetric(self, root) -> bool:
1011
def is_mirror(left, right):
1112
if not left and not right:
1213
return True
1314
if not left or not right:
1415
return False
15-
return (left.val == right.val and
16-
is_mirror(left.left, right.right) and
17-
is_mirror(left.right, right.left))
18-
16+
return (
17+
left.val == right.val
18+
and is_mirror(left.left, right.right)
19+
and is_mirror(left.right, right.left)
20+
)
21+
1922
if not root:
2023
return True
21-
22-
return is_mirror(root.left, root.right)
2324

25+
return is_mirror(root.left, root.right)

solutions/102/01.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,28 @@
88
from typing import List
99
from collections import deque
1010

11+
1112
class Solution:
1213
def levelOrder(self, root) -> List[List[int]]:
1314
if not root:
1415
return []
15-
16+
1617
res = []
1718
queue = deque([root])
18-
19+
1920
while queue:
2021
level_size = len(queue)
2122
level = []
22-
23+
2324
for _ in range(level_size):
2425
node = queue.popleft()
2526
level.append(node.val)
26-
27+
2728
if node.left:
2829
queue.append(node.left)
2930
if node.right:
3031
queue.append(node.right)
31-
32+
3233
res.append(level)
33-
34-
return res
3534

35+
return res

0 commit comments

Comments
 (0)