mirror of
https://github.com/prdlk/leetcode.git
synced 2026-11-02 13:12:44 +00:00
docs(docs): add Approach diagrams and Explanation sections to LeetCode problem documentation
This commit is contained in:
1 parent
b8c779903f
commit
23eb71d387
19 files changed
+439
No files matched your search
@@ -21,6 +21,20 @@ sidebar:
|
|||||||
- `1 <= k <= nums.length <= 10^5`
|
- `1 <= k <= nums.length <= 10^5`
|
||||||
- `-10^4 <= nums[i] <= 10^4`
|
- `-10^4 <= nums[i] <= 10^4`
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["findKthLargest(nums, k)"]) --> F{"more i in range(len(nums))?"}
|
||||||
|
F -- yes --> N["nums[i] = -nums[i] — negate so the min-heap acts as a max-heap"]
|
||||||
|
N --> F
|
||||||
|
F -- no --> H["heapq.heapify(nums)"]
|
||||||
|
H --> W{"more _ in range(k - 1)?"}
|
||||||
|
W -- yes --> P["heapq.heappop(nums) — discard the k-1 largest"]
|
||||||
|
P --> W
|
||||||
|
W -- no --> E(["return -heapq.heappop(nums)"])
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -39,3 +53,7 @@ class Solution:
|
|||||||
|
|
||||||
return -heapq.heappop(nums)
|
return -heapq.heappop(nums)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="XEmy13g1Qxc" title="Kth Largest Element in an Array - Quick Select - Leetcode 215 - Python" />
|
||||||
@@ -27,6 +27,27 @@ Could you write a generalized algorithm to work on any possible set of character
|
|||||||
- `0 <= strs[i].length <= 200`
|
- `0 <= strs[i].length <= 200`
|
||||||
- `strs[i]` contains any possible characters out of 256 valid ASCII characters.
|
- `strs[i]` contains any possible characters out of 256 valid ASCII characters.
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
::::warning
|
||||||
|
The diagram traces the code below literally. That code does not solve the problem: both `encode` and `decode` have only a docstring for a body, so each returns `None` and `codec.decode(codec.encode(strs))` yields `None` instead of `strs`.
|
||||||
|
::::
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
subgraph state["state — Codec holds no fields"]
|
||||||
|
X["Codec() — nothing is stored between encode and decode"]
|
||||||
|
end
|
||||||
|
subgraph encode["encode(strs)"]
|
||||||
|
E1["docstring only — no statement runs"] --> E2(["return None"])
|
||||||
|
end
|
||||||
|
subgraph decode["decode(s)"]
|
||||||
|
D1["docstring only — no statement runs"] --> D2(["return None"])
|
||||||
|
end
|
||||||
|
state --> encode
|
||||||
|
state --> decode
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -46,3 +67,7 @@ class Codec:
|
|||||||
# codec = Codec()
|
# codec = Codec()
|
||||||
# codec.decode(codec.encode(strs))
|
# codec.decode(codec.encode(strs))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="B1k_sxOSgv8" title="Encode and Decode Strings - Leetcode 271 - Python" />
|
||||||
@@ -22,6 +22,22 @@ sidebar:
|
|||||||
- `1 <= n <= 20`
|
- `1 <= n <= 20`
|
||||||
- `-1000 <= matrix[i][j] <= 1000`
|
- `-1000 <= matrix[i][j] <= 1000`
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["rotate(matrix)"]) --> N["n = len(matrix)"]
|
||||||
|
N --> F{"more r in range(n)?"}
|
||||||
|
F -- yes --> G{"more c in range(r + 1, n)?"}
|
||||||
|
G -- yes --> T["swap matrix[r][c] and matrix[c][r] — transpose across the diagonal"]
|
||||||
|
T --> G
|
||||||
|
G -- no --> F
|
||||||
|
F -- no --> H{"more r in range(n)?"}
|
||||||
|
H -- yes --> R["matrix[r].reverse() — transpose then mirror is a clockwise turn"]
|
||||||
|
R --> H
|
||||||
|
H -- no --> E(["return None — rotated in place"])
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -35,3 +51,7 @@ class Solution:
|
|||||||
for r in range(n):
|
for r in range(n):
|
||||||
matrix[r].reverse()
|
matrix[r].reverse()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="fMSJSS7eO1w" title="Rotate Image - Matrix - Leetcode 48" />
|
||||||
@@ -23,6 +23,24 @@ sidebar:
|
|||||||
- `1 <= m, n <= 10`
|
- `1 <= m, n <= 10`
|
||||||
- `-100 <= matrix[i][j] <= 100`
|
- `-100 <= matrix[i][j] <= 100`
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["spiralOrder(matrix)"]) --> I["res = [], top = 0, bottom = len(matrix) - 1, left = 0, right = len(matrix[0]) - 1"]
|
||||||
|
I --> W{"top <= bottom and left <= right?"}
|
||||||
|
W -- no --> E(["return res"])
|
||||||
|
W -- yes --> T["append matrix[top][c] for c in left..right, then top += 1 — top row, shrink from above"]
|
||||||
|
T --> R["append matrix[r][right] for r in top..bottom, then right -= 1 — right column"]
|
||||||
|
R --> B{"top <= bottom?"}
|
||||||
|
B -- yes --> C["append matrix[bottom][c] for c in right down to left, then bottom -= 1 — bottom row"]
|
||||||
|
C --> L{"left <= right?"}
|
||||||
|
B -- no --> L
|
||||||
|
L -- yes --> D["append matrix[r][left] for r in bottom down to top, then left += 1 — left column"]
|
||||||
|
D --> W
|
||||||
|
L -- no --> W
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -57,3 +75,7 @@ class Solution:
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="BJnMZNwUk1M" title="Spiral Matrix - Microsoft Interview Question - Leetcode 54" />
|
||||||
@@ -30,6 +30,35 @@ You must do it in place.
|
|||||||
- A simple improvement uses O(m + n) space, but still not the best solution.
|
- A simple improvement uses O(m + n) space, but still not the best solution.
|
||||||
- Could you devise a constant space solution?
|
- Could you devise a constant space solution?
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["setZeroes(matrix)"]) --> I["m = len(matrix), n = len(matrix[0])"]
|
||||||
|
I --> Z["row0_zero = any(matrix[0][c] == 0), col0_zero = any(matrix[r][0] == 0) — remember before they become markers"]
|
||||||
|
Z --> F{"more r in range(1, m)?"}
|
||||||
|
F -- yes --> G{"more c in range(1, n)?"}
|
||||||
|
G -- yes --> Q{"matrix[r][c] == 0?"}
|
||||||
|
Q -- yes --> M["matrix[r][0] = 0, matrix[0][c] = 0 — row 0 and column 0 are the marker lists"]
|
||||||
|
M --> G
|
||||||
|
Q -- no --> G
|
||||||
|
G -- no --> F
|
||||||
|
F -- no --> H{"more r in range(1, m)?"}
|
||||||
|
H -- yes --> J{"more c in range(1, n)?"}
|
||||||
|
J -- yes --> K{"matrix[r][0] == 0 or matrix[0][c] == 0?"}
|
||||||
|
K -- yes --> W["matrix[r][c] = 0"]
|
||||||
|
W --> J
|
||||||
|
K -- no --> J
|
||||||
|
J -- no --> H
|
||||||
|
H -- no --> A{"row0_zero?"}
|
||||||
|
A -- yes --> B["matrix[0][c] = 0 for c in range(n)"]
|
||||||
|
B --> C{"col0_zero?"}
|
||||||
|
A -- no --> C
|
||||||
|
C -- yes --> D["matrix[r][0] = 0 for r in range(m)"]
|
||||||
|
D --> E(["return None — zeroed in place"])
|
||||||
|
C -- no --> E
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -65,3 +94,7 @@ class Solution:
|
|||||||
for r in range(m):
|
for r in range(m):
|
||||||
matrix[r][0] = 0
|
matrix[r][0] = 0
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="T41rL0L3Pnw" title="Set Matrix Zeroes - In-place - Leetcode 73" />
|
||||||
@@ -23,6 +23,23 @@ sidebar:
|
|||||||
- `1 <= k <= points.length <= 10^4`
|
- `1 <= k <= points.length <= 10^4`
|
||||||
- `-10^4 <= xi, yi <= 10^4`
|
- `-10^4 <= xi, yi <= 10^4`
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["kClosest(points, k)"]) --> I["minHeap = []"]
|
||||||
|
I --> F{"more x, y in points?"}
|
||||||
|
F -- yes --> D["dist = x**2 + y**2 — squared distance orders the same as sqrt"]
|
||||||
|
D --> A["minHeap.append([dist, x, y])"]
|
||||||
|
A --> F
|
||||||
|
F -- no --> H["heapq.heapify(minHeap), res = [] — O(n) build, smallest dist on top"]
|
||||||
|
H --> W{"k > 0?"}
|
||||||
|
W -- yes --> P["dist, x, y = heapq.heappop(minHeap)"]
|
||||||
|
P --> R["res.append([x, y]), k -= 1"]
|
||||||
|
R --> W
|
||||||
|
W -- no --> E(["return res"])
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -46,3 +63,7 @@ class Solution:
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="rI2EBUEMfTk" title="K Closest Points to Origin - Heap / Priority Queue - Leetcode 973 - Python" />
|
||||||
@@ -19,6 +19,44 @@ sidebar:
|
|||||||
- `word` and `prefix` consist only of lowercase English letters.
|
- `word` and `prefix` consist only of lowercase English letters.
|
||||||
- At most 3 * 10^4 calls in total will be made to insert, search, and startsWith.
|
- At most 3 * 10^4 calls in total will be made to insert, search, and startsWith.
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
subgraph state["state — root TrieNode; every node holds a children dict and an endOfWord flag"]
|
||||||
|
R["root"] --- C["... children[c] ..."] --- L["endOfWord = True — a word ends here"]
|
||||||
|
end
|
||||||
|
subgraph insert["insert(word)"]
|
||||||
|
I1["cur = root"] --> I2{"more c in word?"}
|
||||||
|
I2 -- yes --> I3{"c not in cur.children?"}
|
||||||
|
I3 -- yes --> I4["cur.children[c] = TrieNode()"]
|
||||||
|
I4 --> I5["cur = cur.children[c]"]
|
||||||
|
I3 -- no --> I5
|
||||||
|
I5 --> I2
|
||||||
|
I2 -- no --> I6["cur.endOfWord = True"]
|
||||||
|
I6 --> I7(["done"])
|
||||||
|
end
|
||||||
|
subgraph search["search(word)"]
|
||||||
|
S1["cur = root"] --> S2{"more c in word?"}
|
||||||
|
S2 -- yes --> S3{"c not in cur.children?"}
|
||||||
|
S3 -- yes --> S4(["return False"])
|
||||||
|
S3 -- no --> S5["cur = cur.children[c]"]
|
||||||
|
S5 --> S2
|
||||||
|
S2 -- no --> S6(["return cur.endOfWord — the path exists, but is it a whole word?"])
|
||||||
|
end
|
||||||
|
subgraph startsWith["startsWith(prefix)"]
|
||||||
|
P1["cur = root"] --> P2{"more c in prefix?"}
|
||||||
|
P2 -- yes --> P3{"c not in cur.children?"}
|
||||||
|
P3 -- yes --> P4(["return False"])
|
||||||
|
P3 -- no --> P5["cur = cur.children[c]"]
|
||||||
|
P5 --> P2
|
||||||
|
P2 -- no --> P6(["return True — every prefix char had a path"])
|
||||||
|
end
|
||||||
|
state --> insert
|
||||||
|
state --> search
|
||||||
|
state --> startsWith
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -68,3 +106,7 @@ class Trie:
|
|||||||
# param_2 = obj.search(word)
|
# param_2 = obj.search(word)
|
||||||
# param_3 = obj.startsWith(prefix)
|
# param_3 = obj.startsWith(prefix)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="oobqoCJlHA0" title="Implement Trie (Prefix Tree) - Leetcode 208" />
|
||||||
@@ -27,6 +27,20 @@ sidebar:
|
|||||||
- `0 <= Node.val <= 9`
|
- `0 <= Node.val <= 9`
|
||||||
- It is guaranteed that the list represents a number that does not have leading zeros.
|
- It is guaranteed that the list represents a number that does not have leading zeros.
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["addTwoNumbers(l1, l2)"]) --> I["dummy = ListNode(), carry = 0, curr = dummy — dummy.next will be the head"]
|
||||||
|
I --> W{"l1 or l2 or carry?"}
|
||||||
|
W -- no --> E(["return dummy.next"])
|
||||||
|
W -- yes --> A["s = (l1.val if l1 else 0) + (l2.val if l2 else 0) + carry — a missing digit counts as 0"]
|
||||||
|
A --> D["carry, val = divmod(s, 10)"]
|
||||||
|
D --> N["curr.next = ListNode(val), curr = curr.next"]
|
||||||
|
N --> V["l1 = l1.next if l1 else None, l2 = l2.next if l2 else None"]
|
||||||
|
V --> W
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -55,3 +69,7 @@ class Solution:
|
|||||||
|
|
||||||
return dummy.next
|
return dummy.next
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="wgFPrzTjm7s" title="Add Two Numbers - Leetcode 2 - Python" />
|
||||||
@@ -30,6 +30,27 @@ sidebar:
|
|||||||
- `lists[i]` is sorted in ascending order.
|
- `lists[i]` is sorted in ascending order.
|
||||||
- The sum of lists[i].length will not exceed 10^4.
|
- The sum of lists[i].length will not exceed 10^4.
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["mergeKLists(lists)"]) --> I["heap = []"]
|
||||||
|
I --> F{"more i, node in enumerate(lists)?"}
|
||||||
|
F -- yes --> C{"node?"}
|
||||||
|
C -- yes --> P["heapq.heappush(heap, (node.val, i, node)) — i breaks ties so nodes are never compared"]
|
||||||
|
P --> F
|
||||||
|
C -- no --> F
|
||||||
|
F -- no --> D["D = ListNode(), cur = D"]
|
||||||
|
D --> W{"heap?"}
|
||||||
|
W -- no --> E(["return D.next"])
|
||||||
|
W -- yes --> O["val, i, node = heapq.heappop(heap) — the smallest head across all lists"]
|
||||||
|
O --> L["cur.next = node, cur = node, node = node.next"]
|
||||||
|
L --> N{"node?"}
|
||||||
|
N -- yes --> Q["heapq.heappush(heap, (node.val, i, node))"]
|
||||||
|
Q --> W
|
||||||
|
N -- no --> W
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -67,3 +88,7 @@ class Solution:
|
|||||||
# Space: O(n)
|
# Space: O(n)
|
||||||
return D.next
|
return D.next
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="q5a5OiGbT6Q" title="Merge K Sorted Lists - Leetcode 23 - Python" />
|
||||||
@@ -16,6 +16,43 @@ sidebar:
|
|||||||
- There will be at most 2 dots in `word` for search queries.
|
- There will be at most 2 dots in `word` for search queries.
|
||||||
- At most 10^4 calls will be made to addWord and search.
|
- At most 10^4 calls will be made to addWord and search.
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
subgraph state["state — root TrieNode; every node holds a children dict and an endOfWord flag"]
|
||||||
|
R["root"] --- C["... children[c] ..."] --- L["endOfWord = True — a word ends here"]
|
||||||
|
end
|
||||||
|
subgraph addWord["addWord(word)"]
|
||||||
|
A1["cur = root"] --> A2{"more c in word?"}
|
||||||
|
A2 -- yes --> A3{"c not in cur.children?"}
|
||||||
|
A3 -- yes --> A4["cur.children[c] = TrieNode()"]
|
||||||
|
A4 --> A5["cur = cur.children[c]"]
|
||||||
|
A3 -- no --> A5
|
||||||
|
A5 --> A2
|
||||||
|
A2 -- no --> A6["cur.endOfWord = True"]
|
||||||
|
A6 --> A7(["done"])
|
||||||
|
end
|
||||||
|
subgraph search["search(word)"]
|
||||||
|
S1["dfs(0, root) — match from index 0 at the root"] --> S2["cur = root"]
|
||||||
|
S2 --> S3{"more i in range(j, len(word))?"}
|
||||||
|
S3 -- no --> S4(["return cur.endOfWord"])
|
||||||
|
S3 -- yes --> S5["c = word[i]"]
|
||||||
|
S5 --> S6{"c == '.'?"}
|
||||||
|
S6 -- yes --> S7{"more child in cur.children.values()?"}
|
||||||
|
S7 -- yes --> S8{"dfs(i + 1, child)? — try the rest of the word from this child"}
|
||||||
|
S8 -- yes --> S9(["return True"])
|
||||||
|
S8 -- no --> S7
|
||||||
|
S7 -- no --> S10(["return False — no child matched the wildcard"])
|
||||||
|
S6 -- no --> S11{"c not in cur.children?"}
|
||||||
|
S11 -- yes --> S12(["return False"])
|
||||||
|
S11 -- no --> S13["cur = cur.children[c]"]
|
||||||
|
S13 --> S3
|
||||||
|
end
|
||||||
|
state --> addWord
|
||||||
|
state --> search
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -63,3 +100,7 @@ class WordDictionary:
|
|||||||
# obj.addWord(word)
|
# obj.addWord(word)
|
||||||
# param_2 = obj.search(word)
|
# param_2 = obj.search(word)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="BTf05gs_8iU" title="Design Add and Search Words Data Structure - Leetcode 211 - Python" />
|
||||||
@@ -25,6 +25,26 @@ sidebar:
|
|||||||
- The number of nodes in the tree is in the range [0, 2000].
|
- The number of nodes in the tree is in the range [0, 2000].
|
||||||
- `-1000 <= Node.val <= 1000`
|
- `-1000 <= Node.val <= 1000`
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["levelOrder(root)"]) --> I["res = [], q = deque(), q.append(root)"]
|
||||||
|
I --> W{"q non-empty?"}
|
||||||
|
W -- no --> E(["return res"])
|
||||||
|
W -- yes --> L["qLen = len(q), level = [] — qLen freezes the current level's size"]
|
||||||
|
L --> F{"more i in range(qLen)?"}
|
||||||
|
F -- no --> V{"level non-empty?"}
|
||||||
|
V -- yes --> A["res.append(level)"]
|
||||||
|
A --> W
|
||||||
|
V -- no --> W
|
||||||
|
F -- yes --> P["node = q.popleft()"]
|
||||||
|
P --> N{"node is not None?"}
|
||||||
|
N -- no --> F
|
||||||
|
N -- yes --> C["level.append(node.val), q.append(node.left), q.append(node.right) — None children are filtered on the next level"]
|
||||||
|
C --> F
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -59,3 +79,7 @@ class Solution:
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="6ZnyEApgFYg" title="Binary Tree Level Order Traversal - BFS - Leetcode 102" />
|
||||||
@@ -21,6 +21,16 @@ sidebar:
|
|||||||
- The number of nodes in the tree is in the range [0, 10^4].
|
- The number of nodes in the tree is in the range [0, 10^4].
|
||||||
- `-100 <= Node.val <= 100`
|
- `-100 <= Node.val <= 100`
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["maxDepth(root)"]) --> B{"root is None?"}
|
||||||
|
B -- yes --> Z(["return 0"])
|
||||||
|
B -- no --> L["l = maxDepth(root.left), r = maxDepth(root.right)"]
|
||||||
|
L --> E(["return 1 + max(l, r) — this node adds one level above its deeper subtree"])
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -37,3 +47,7 @@ class Solution:
|
|||||||
|
|
||||||
return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
|
return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="hTM3phVI6YQ" title="Maximum Depth of Binary Tree - 3 Solutions - Leetcode 104 - Python" />
|
||||||
@@ -28,6 +28,22 @@ sidebar:
|
|||||||
- The number of nodes in the binary tree is in the range [1, 10^5].
|
- The number of nodes in the binary tree is in the range [1, 10^5].
|
||||||
- Each node's value is between [-10^4, 10^4].
|
- Each node's value is between [-10^4, 10^4].
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["goodNodes(root)"]) --> C["dfs(root, root.val) — the root is always good"]
|
||||||
|
C --> E(["return that count"])
|
||||||
|
subgraph dfs["dfs(node, max_val)"]
|
||||||
|
D1{"node is None?"} -- yes --> D2(["return 0"])
|
||||||
|
D1 -- no --> D3["is_good = 1 if node.val >= max_val else 0 — max_val is the largest value on the path so far"]
|
||||||
|
D3 --> D4["new_max = max(max_val, node.val)"]
|
||||||
|
D4 --> D5["l = dfs(node.left, new_max), r = dfs(node.right, new_max)"]
|
||||||
|
D5 --> D6(["return is_good + l + r"])
|
||||||
|
end
|
||||||
|
C --> dfs
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -50,3 +66,7 @@ class Solution:
|
|||||||
|
|
||||||
return dfs(root, root.val)
|
return dfs(root, root.val)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="7cp5imvDzl4" title="Microsoft's Most Asked Question 2021 - Count Good Nodes in a Binary Tree - Leetcode 1448 - Python" />
|
||||||
@@ -29,6 +29,26 @@ sidebar:
|
|||||||
- The number of nodes in the tree is in the range [0, 100].
|
- The number of nodes in the tree is in the range [0, 100].
|
||||||
- `-100 <= Node.val <= 100`
|
- `-100 <= Node.val <= 100`
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["rightSideView(root)"]) --> I["res = [], q = deque([root])"]
|
||||||
|
I --> W{"q non-empty?"}
|
||||||
|
W -- no --> E(["return res"])
|
||||||
|
W -- yes --> L["rightSide = None, qLen = len(q) — qLen freezes the current level's size"]
|
||||||
|
L --> F{"more i in range(qLen)?"}
|
||||||
|
F -- no --> V{"rightSide is not None?"}
|
||||||
|
V -- yes --> A["res.append(rightSide.val) — the last real node popped on this level is the rightmost"]
|
||||||
|
A --> W
|
||||||
|
V -- no --> W
|
||||||
|
F -- yes --> P["node = q.popleft()"]
|
||||||
|
P --> N{"node is not None?"}
|
||||||
|
N -- no --> F
|
||||||
|
N -- yes --> C["rightSide = node, q.append(node.left), q.append(node.right)"]
|
||||||
|
C --> F
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -62,3 +82,7 @@ class Solution:
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="d4zLyf32e3I" title="Binary Tree Right Side View - Breadth First Search - Leetcode 199" />
|
||||||
@@ -25,6 +25,17 @@ sidebar:
|
|||||||
- The number of nodes in the tree is in the range [0, 100].
|
- The number of nodes in the tree is in the range [0, 100].
|
||||||
- `-100 <= Node.val <= 100`
|
- `-100 <= Node.val <= 100`
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["invertTree(root)"]) --> B{"root is None?"}
|
||||||
|
B -- yes --> Z(["return None"])
|
||||||
|
B -- no --> L["left = invertTree(root.left), right = invertTree(root.right) — both subtrees are already inverted"]
|
||||||
|
L --> X["root.left = right, root.right = left"]
|
||||||
|
X --> E(["return root"])
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -47,3 +58,7 @@ class Solution:
|
|||||||
|
|
||||||
return root
|
return root
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="OnSn2XEQ4MY" title="Invert Binary Tree - Depth First Search - Leetcode 226" />
|
||||||
@@ -26,6 +26,23 @@ If the BST is modified often (i.e., we can do insert and delete operations) and
|
|||||||
- `1 <= k <= n <= 10^4`
|
- `1 <= k <= n <= 10^4`
|
||||||
- `0 <= Node.val <= 10^4`
|
- `0 <= Node.val <= 10^4`
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["kthSmallest(root, k)"]) --> I["n = 0, stack = [], cur = root"]
|
||||||
|
I --> W{"cur or stack?"}
|
||||||
|
W -- no --> E(["fall off the loop — unreachable, k <= n"])
|
||||||
|
W -- yes --> L{"cur?"}
|
||||||
|
L -- yes --> P["stack.append(cur), cur = cur.left — push the whole left spine"]
|
||||||
|
P --> L
|
||||||
|
L -- no --> O["cur = stack.pop(), n += 1 — nodes pop in ascending order"]
|
||||||
|
O --> K{"n == k?"}
|
||||||
|
K -- yes --> R(["return cur.val"])
|
||||||
|
K -- no --> N["cur = cur.right"]
|
||||||
|
N --> W
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -52,3 +69,7 @@ class Solution:
|
|||||||
return cur.val
|
return cur.val
|
||||||
cur = cur.right
|
cur = cur.right
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="5LUXSvjmGCw" title="Kth Smallest Element in a BST - Leetcode 230 - Python" />
|
||||||
@@ -30,6 +30,22 @@ sidebar:
|
|||||||
- `p != q`
|
- `p != q`
|
||||||
- p and q will exist in the BST.
|
- p and q will exist in the BST.
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["lowestCommonAncestor(root, p, q)"]) --> I["cur = root"]
|
||||||
|
I --> W{"cur?"}
|
||||||
|
W -- no --> E(["fall off the loop — unreachable, p and q exist in the BST"])
|
||||||
|
W -- yes --> A{"p.val < cur.val and q.val < cur.val?"}
|
||||||
|
A -- yes --> L["cur = cur.left — both sit in the left subtree"]
|
||||||
|
L --> W
|
||||||
|
A -- no --> B{"p.val > cur.val and q.val > cur.val?"}
|
||||||
|
B -- yes --> R["cur = cur.right — both sit in the right subtree"]
|
||||||
|
R --> W
|
||||||
|
B -- no --> C(["return cur — the paths to p and q split here"])
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -54,3 +70,7 @@ class Solution:
|
|||||||
else:
|
else:
|
||||||
return cur
|
return cur
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="gs2LMfuOR9k" title="Lowest Common Ancestor of a Binary Search Tree - Leetcode 235 - Python" />
|
||||||
@@ -30,6 +30,21 @@ sidebar:
|
|||||||
- `p != q`
|
- `p != q`
|
||||||
- p and q will exist in the tree.
|
- p and q will exist in the tree.
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["lowestCommonAncestor(root, p, q)"]) --> B{"not root?"}
|
||||||
|
B -- yes --> N(["return None"])
|
||||||
|
B -- no --> M{"root == p or root == q?"}
|
||||||
|
M -- yes --> R(["return root — a node is its own ancestor"])
|
||||||
|
M -- no --> L["l = self.lowestCommonAncestor(root.left, p, q)"]
|
||||||
|
L --> Q["r = self.lowestCommonAncestor(root.right, p, q)"]
|
||||||
|
Q --> D{"l and r?"}
|
||||||
|
D -- yes --> A(["return root — p and q were found on different sides"])
|
||||||
|
D -- no --> E(["return l or r — pass up whichever side found something"])
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
|
|||||||
@@ -22,6 +22,23 @@ sidebar:
|
|||||||
- The number of nodes in the tree is in the range [1, 10^4].
|
- The number of nodes in the tree is in the range [1, 10^4].
|
||||||
- `-2^31 <= Node.val <= 2^31 - 1`
|
- `-2^31 <= Node.val <= 2^31 - 1`
|
||||||
|
|
||||||
|
## Approach
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
S(["isValidBST(root)"]) --> C["valid(root, float('-inf'), float('inf')) — the root may hold any value"]
|
||||||
|
C --> E(["return that result"])
|
||||||
|
subgraph valid["valid(node, low, high)"]
|
||||||
|
V1{"not node?"}
|
||||||
|
V1 -- yes --> V2(["return True"])
|
||||||
|
V1 -- no --> V3{"not (low < node.val < high)?"}
|
||||||
|
V3 -- yes --> V4(["return False — node breaks a bound set by an ancestor"])
|
||||||
|
V3 -- no --> V5["valid(node.left, low, node.val) and valid(node.right, node.val, high) — each child tightens one bound"]
|
||||||
|
V5 --> V6(["return that result"])
|
||||||
|
end
|
||||||
|
C --> V1
|
||||||
|
```
|
||||||
|
|
||||||
## Solution
|
## Solution
|
||||||
|
|
||||||
```py
|
```py
|
||||||
@@ -44,3 +61,7 @@ class Solution:
|
|||||||
|
|
||||||
return valid(root, float("-inf"), float("inf"))
|
return valid(root, float("-inf"), float("inf"))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
<YouTube id="s6ATEkipzow" title="Validate Binary Search Tree - Depth First Search - Leetcode 98" />
|
||||||
Reference in new issue
Block a user