Compare commits

...
12 changed files with 742 additions and 0 deletions

No files matched your search

@@ -0,0 +1,61 @@
---
title: '102. Binary Tree Level Order Traversal'
description: Given the root of a binary tree, return the level order traversal of its nodes' values. (i.e., from left to right, level by level)
sidebar:
label: 'Binary Tree Level Order Traversal'
badge: 'Medium'
---
<Badge variant="accent">Tree BFS</Badge>
### Example 1:
- Input: `root = [3,9,20,null,null,15,7]`
- Output: `[[3],[9,20],[15,7]]`
### Example 2:
- Input: `root = [1]`
- Output: `[[1]]`
### Example 3:
- Input: `root = []`
- Output: `[]`
### Constraints:
- The number of nodes in the tree is in the range [0, 2000].
- `-1000 <= Node.val <= 1000`
## Solution
```py
# 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
from collections import deque
class Solution:
# T: O(n) S: O(n)
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
res = []
q = deque()
q.append(root)
while q:
qLen = len(q)
level = []
for i in range(qLen):
node = q.popleft()
if node:
level.append(node.val)
q.append(node.left)
q.append(node.right)
if level:
res.append(level)
return res
```
@@ -0,0 +1,39 @@
---
title: '104. Maximum Depth of Binary Tree'
description: Given the root of a binary tree, return its maximum depth
sidebar:
label: 'Maximum Depth of Binary Tree'
badge: 'Easy'
---
<Badge variant="accent">Tree DFS</Badge>
### Example 1:
- Input: `root = [3,9,20,null,null,15,7]`
- Output: `3`
### Example 2:
- Input: `root = [1,null,2]`
- Output: `2`
### Constraints:
- The number of nodes in the tree is in the range [0, 10^4].
- `-100 <= Node.val <= 100`
## Solution
```py
# 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 maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
```
@@ -0,0 +1,52 @@
---
title: '1448. Count Good Nodes in Binary Tree'
description: Given a binary tree root, a node X in the tree is named good if in the path from root to X there are no nodes with a value greater than X
sidebar:
label: 'Count Good Nodes in Binary Tree'
badge: 'Medium'
---
<Badge variant="accent">Tree BFS</Badge>
### Example 1:
- Input: `root = [3,1,4,3,null,1,5]`
- Output: `4`
- Explanation: Nodes in blue are good. Root Node `(3`) is always a good node. Node `4` -> (3,4) is the maximum value in the path starting from the `root`. Node `5` -> (3,4,5) is the maximum value in the path Node `3` -> (3,1,3) is the maximum value in the path.
### Example 2:
- Input: `root = [3,3,null,4,2]`
- Output: `3`
- Explanation: Node `2` -> `(3`, `3`, `2`) is not good, because `"3`" is higher than it.
### Example 3:
- Input: `root = [1]`
- Output: `1`
- Explanation: Root is considered as good.
### Constraints:
- 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].
## Solution
```py
# 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 goodNodes(self, root: TreeNode) -> int:
def dfs(node, max_val):
if not node:
return 0
is_good = 1 if node.val >= max_val else 0
new_max = max(max_val, node.val)
return is_good + dfs(node.left, new_max) + dfs(node.right, new_max)
return dfs(root, root.val)
```
@@ -0,0 +1,64 @@
---
title: '199. Binary Tree Right Side View'
description: Given the root of a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom
sidebar:
label: 'Binary Tree Right Side View'
badge: 'Medium'
---
<Badge variant="accent">Tree BFS</Badge>
### Example 1:
- Input: `root = [1,2,3,null,5,null,4]`
- Output: `[1,3,4]`
### Example 2:
- Input: `root = [1,2,3,4,null,null,null,5]`
- Output: `[1,3,4,5]`
### Example 3:
- Input: `root = [1,null,3]`
- Output: `[1,3]`
### Example 4:
- Input: `root = []`
- Output: `[]`
### Constraints:
- The number of nodes in the tree is in the range [0, 100].
- `-100 <= Node.val <= 100`
## Solution
```py
# 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
from collections import deque
class Solution:
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
res = []
q = deque([root])
while q:
rightSide = None
qLen = len(q)
for i in range(qLen):
node = q.popleft()
if node:
rightSide = node
q.append(node.left)
q.append(node.right)
if rightSide:
res.append(rightSide.val)
return res
```
@@ -0,0 +1,49 @@
---
title: '226. Invert Binary Tree'
description: Given the root of a binary tree, invert the tree, and return its root
sidebar:
label: 'Invert Binary Tree'
badge: 'Easy'
---
<Badge variant="accent">Tree DFS</Badge>
### Example 1:
- Input: `root = [4,2,7,1,3,6,9]`
- Output: `[4,7,2,9,6,3,1]`
### Example 2:
- Input: `root = [2,1,3]`
- Output: `[2,3,1]`
### Example 3:
- Input: `root = []`
- Output: `[]`
### Constraints:
- The number of nodes in the tree is in the range [0, 100].
- `-100 <= Node.val <= 100`
## Solution
```py
# 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 invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return None
left = self.invertTree(root.left)
right = self.invertTree(root.right)
root.left = right
root.right = left
return root
```
@@ -0,0 +1,62 @@
---
title: '236. Lowest Common Ancestor of a Binary Tree'
description: Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree
sidebar:
label: 'Lowest Common Ancestor of a Binary Tree'
badge: 'Medium'
---
<Badge variant="accent">Tree DFS</Badge>
### Example 1:
- Input: `root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1`
- Output: `3`
- Explanation: The LCA of nodes `5` and `1` is `3`.
### Example 2:
- Input: `root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4`
- Output: `5`
- Explanation: The LCA of nodes `5` and `4` is `5`, since a node can be a descendant of itself according to the LCA definition.
### Example 3:
- Input: `root = [1,2], p = 1, q = 2`
- Output: `1`
### Constraints:
- The number of nodes in the tree is in the range [2, 10^5].
- `-10^9 <= Node.val <= 10^9`
- All Node.val are unique.
- `p != q`
- p and q will exist in the tree.
## Solution
```py
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(
self, root: "TreeNode", p: "TreeNode", q: "TreeNode"
) -> "TreeNode":
if not root:
return None
if root == p or root == q:
return root
l = self.lowestCommonAncestor(root.left, p, q)
r = self.lowestCommonAncestor(root.right, p, q)
if l and r:
return root
else:
return l or r
```
@@ -0,0 +1,46 @@
"""
104. Maximum Depth of Binary Tree
Difficulty: Easy
https://leetcode.com/problems/maximum-depth-of-binary-tree/
──────────────────────────────────────────────────
Given the root of a binary tree, return its maximum depth.
A binary tree's maximum depth is the number of nodes along the
longest path from the root node down to the farthest leaf node.
Example 1:
Input: root = [3,9,20,null,null,15,7]
Output: 3
Example 2:
Input: root = [1,null,2]
Output: 2
Constraints:
• The number of nodes in the tree is in the range [0, 10^4].
• -100 <= Node.val <= 100
"""
# 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 maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
@@ -0,0 +1,54 @@
"""
226. Invert Binary Tree
Difficulty: Easy
https://leetcode.com/problems/invert-binary-tree/
──────────────────────────────────────────────────
Given the root of a binary tree, invert the tree, and return its root.
Example 1:
Input: root = [4,2,7,1,3,6,9]
Output: [4,7,2,9,6,3,1]
Example 2:
Input: root = [2,1,3]
Output: [2,3,1]
Example 3:
Input: root = []
Output: []
Constraints:
• The number of nodes in the tree is in the range [0, 100].
• -100 <= Node.val <= 100
"""
# 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 invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root:
return None
left = self.invertTree(root.left)
right = self.invertTree(root.right)
root.left = right
root.right = left
return root
@@ -0,0 +1,66 @@
"""
102. Binary Tree Level Order Traversal
Difficulty: Medium
https://leetcode.com/problems/binary-tree-level-order-traversal/
──────────────────────────────────────────────────
Given the root of a binary tree, return the level order traversal of
its nodes' values. (i.e., from left to right, level by level).
Example 1:
Input: root = [3,9,20,null,null,15,7]
Output: [[3],[9,20],[15,7]]
Example 2:
Input: root = [1]
Output: [[1]]
Example 3:
Input: root = []
Output: []
Constraints:
• The number of nodes in the tree is in the range [0, 2000].
• -1000 <= Node.val <= 1000
"""
# 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
from collections import deque
class Solution:
# T: O(n) S: O(n)
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
res = []
q = deque()
q.append(root)
while q:
qLen = len(q)
level = []
for i in range(qLen):
node = q.popleft()
if node:
level.append(node.val)
q.append(node.left)
q.append(node.right)
if level:
res.append(level)
return res
@@ -0,0 +1,94 @@
"""
1448. Count Good Nodes in Binary Tree
Difficulty: Medium
https://leetcode.com/problems/count-good-nodes-in-binary-tree/
──────────────────────────────────────────────────
Given a binary tree root, a node X in the tree is named good if in
the path from root to X there are no nodes with a value greater than
X.
Return the number of good nodes in the binary tree.
Example 1:
Input: root = [3,1,4,3,null,1,5]
Output: 4
Explanation: Nodes in blue are good.
Root Node (3) is always a good node.
Node 4 -> (3,4) is the maximum value in the path starting from the
root.
Node 5 -> (3,4,5) is the maximum value in the path
Node 3 -> (3,1,3) is the maximum value in the path.
Example 2:
Input: root = [3,3,null,4,2]
Output: 3
Explanation: Node 2 -> (3, 3, 2) is not good, because "3" is higher
than it.
Example 3:
Input: root = [1]
Output: 1
Explanation: Root is considered as good.
Constraints:
• 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].
"""
# 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 goodNodes(self, root: TreeNode) -> int:
def dfs(node, max_val):
if not node:
return 0
is_good = 1 if node.val >= max_val else 0
new_max = max(max_val, node.val)
return is_good + dfs(node.left, new_max) + dfs(node.right, new_max)
return dfs(root, root.val)
@@ -0,0 +1,79 @@
"""
199. Binary Tree Right Side View
Difficulty: Medium
https://leetcode.com/problems/binary-tree-right-side-view/
──────────────────────────────────────────────────
Given the root of a binary tree, imagine yourself standing on the
right side of it, return the values of the nodes you can see ordered
from top to bottom.
Example 1:
Input: root = [1,2,3,null,5,null,4]
Output: [1,3,4]
Explanation:
Example 2:
Input: root = [1,2,3,4,null,null,null,5]
Output: [1,3,4,5]
Explanation:
Example 3:
Input: root = [1,null,3]
Output: [1,3]
Example 4:
Input: root = []
Output: []
Constraints:
• The number of nodes in the tree is in the range [0, 100].
• -100 <= Node.val <= 100
"""
# 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
from collections import deque
class Solution:
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
res = []
q = deque([root])
while q:
rightSide = None
qLen = len(q)
for i in range(qLen):
node = q.popleft()
if node:
rightSide = node
q.append(node.left)
q.append(node.right)
if rightSide:
res.append(rightSide.val)
return res
@@ -0,0 +1,76 @@
"""
236. Lowest Common Ancestor of a Binary Tree
Difficulty: Medium
https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/
──────────────────────────────────────────────────
Given a binary tree, find the lowest common ancestor (LCA) of two
given nodes in the tree.
According to the definition of LCA on Wikipedia: &ldquo;The lowest
common ancestor is defined between two nodes p and q as the lowest
node in T that has both p and q as descendants (where we allow a node
to be a descendant of itself).&rdquo;
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.
Example 2:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a
descendant of itself according to the LCA definition.
Example 3:
Input: root = [1,2], p = 1, q = 2
Output: 1
Constraints:
• The number of nodes in the tree is in the range [2, 10^5].
• -10^9 <= Node.val <= 10^9
• All Node.val are unique.
• p != q
• p and q will exist in the tree.
"""
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(
self, root: "TreeNode", p: "TreeNode", q: "TreeNode"
) -> "TreeNode":
if not root:
return None
if root == p or root == q:
return root
l = self.lowestCommonAncestor(root.left, p, q)
r = self.lowestCommonAncestor(root.right, p, q)
if l and r:
return root
else:
return l or r