Skip to content

Commit 079ab68

Browse files
Merge branch 'main' of https://github.com/contextlab/leetcode-solutions into main
2 parents cc61341 + e146145 commit 079ab68

File tree

1 file changed

+89
-2
lines changed

1 file changed

+89
-2
lines changed

problems/1110/jeremymanning.md

+89-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,98 @@
11
# [Problem 1110: Delete Nodes And Return Forest](https://leetcode.com/problems/delete-nodes-and-return-forest/description/?envType=daily-question)
22

33
## Initial thoughts (stream-of-consciousness)
4+
- Another binary tree problem 🥳🌲🌳!
5+
- Let's keep a list of the roots as we traverse the tree (breadth-first)
6+
- If the current node is in `to_delete`, add both of its children to the "root list" (maybe...but what if they're *also* in the delete list?) and then either remove the node right away, or potentially add it to a list of to-be-deleted nodes
7+
- I think we can just delete it, as long as we enqueue its children (if they exist). To delete the node, we want to set its parent's appropriate child to null...so I think we might want to resurect the `TreeNodeWithParentAndDirection` class from [yesterday's solution](https://github.com/ContextLab/leetcode-solutions/blob/main/problems/2096/jeremymanning.md). I'll use a shorter name this time...that one was a bit clunky.
8+
- Once all of the requested nodes are deleted, we can stop
9+
- If the original root is *not* in `to_delete`, add that to the roots list too
10+
- To account for the "children could be in the delete list too" issue, what about something like this:
11+
- In an initial pass through all nodes, convert to the updated tree structure (with parent/dir fields for each node)
12+
- Also create a hash table (keys: values; values: nodes)
13+
- Now loop through each value in `to_delete`:
14+
- Set the children's parents to None
15+
- Remove the pointer from that node's parent to the node
16+
- Remove the node from the hash table
17+
- Now loop through every node in the hash table one last time. If its parent is None, add it to the root list
418

519
## Refining the problem, round 2 thoughts
20+
- potential edge cases:
21+
- non-unique values: this is explicitly disallowed in the problem definition
22+
- repeated values in `to_delete`: this is also explicitly disallowed
23+
- delete every node in the tree: make sure this returns an empty list
24+
- deleting all but one node: make sure this returns the remaining node
25+
- deal with empty list-- not sure what the right syntax is...maybe `root` would be `None`?
26+
- I think we can go with this solution...
627

728
## Attempted solution(s)
829
```python
9-
class Solution: # paste your code here!
10-
...
30+
class TreeNodePlus(TreeNode):
31+
def __init__(self, val=0, left=None, right=None, parent=None, dir=None):
32+
self.val = val
33+
self.left = left
34+
self.right = right
35+
self.parent = parent
36+
self.dir = dir
37+
38+
class Solution:
39+
def delNodes(self, root: Optional[TreeNode], to_delete: List[int]) -> List[TreeNode]:
40+
if root is None:
41+
return []
42+
43+
nodes = {}
44+
# breadth-first search: convert nodes to TreeNodePlus instances and fill in the hash table
45+
queue = [TreeNodePlus(val=root.val, left=root.left, right=root.right)]
46+
while len(queue) > 0:
47+
node = queue.pop(0)
48+
nodes[node.val] = node
49+
50+
# enqueue children
51+
if node.left is not None:
52+
left = TreeNodePlus(val=node.left.val, left=node.left.left, right=node.left.right, parent=node, dir='L')
53+
node.left = left
54+
queue.append(left)
55+
if node.right is not None:
56+
right = TreeNodePlus(val=node.right.val, left=node.right.left, right=node.right.right, parent=node, dir='R')
57+
node.right = right
58+
queue.append(right)
59+
60+
# now delete all nodes in to_delete
61+
for val in to_delete:
62+
node = nodes[val]
63+
if node.parent is not None:
64+
if node.dir == 'L':
65+
node.parent.left = None
66+
else:
67+
node.parent.right = None
68+
69+
if node.left is not None:
70+
node.left.parent = None
71+
node.left.dir = None
72+
73+
if node.right is not None:
74+
node.right.parent = None
75+
node.right.dir = None
76+
77+
nodes.pop(val)
78+
79+
# now see which nodes are roots
80+
roots = []
81+
for node in nodes.values():
82+
if node.parent is None:
83+
roots.append(node)
84+
85+
return roots
1186
```
87+
- Given test cases pass
88+
- Let's try a few edge cases:
89+
- Empty tree: pass
90+
- Delete nodes that aren't in the actual tree: pass
91+
- Delete all nodes: pass
92+
- Looks ok...submitting!
93+
94+
![Screenshot 2024-07-16 at 11 26 25 PM](https://github.com/user-attachments/assets/0446e1bd-b4cd-4869-a77a-75435cfed489)
95+
96+
- Solved!
97+
- I'm guessing all of that copying is what's so slow...
98+

0 commit comments

Comments
 (0)