Skip to content

Done BFS 2#1596

Open
pranjay01 wants to merge 1 commit intosuper30admin:masterfrom
pranjay01:master
Open

Done BFS 2#1596
pranjay01 wants to merge 1 commit intosuper30admin:masterfrom
pranjay01:master

Conversation

@pranjay01
Copy link
Copy Markdown

No description provided.

@super30admin
Copy link
Copy Markdown
Owner

Right Side View of a tree (Problem1.py)

Your solution has a good structure and you've correctly identified that a level-order traversal (BFS) is suitable for this problem. However, there are a few critical issues that need to be addressed:

  1. Handling Null Root: You must check if the root is null at the beginning and return an empty list immediately. This is important because if the root is null, your code will crash when trying to append root (which is null) to the queue and then later when trying to access node.val.

  2. Avoiding Null Nodes in Queue: Your current code does not check for null nodes when adding children to the queue. This can lead to null nodes being added to the queue, which will cause errors when you try to access their children or value. You should only add non-null children to the queue.

  3. Correct Right Side View Logic: Your approach of appending the first node in the level (i=0) is correct only if the queue is built correctly. However, you are adding the right child first and then the left, which ensures that the rightmost node is processed first in the next level. But note: for the current level, the first node popped is the rightmost node? Actually, in your code, for each level, you are popping the nodes in the order they were added. Since you add the right child first and then the left, the queue for the next level will have the right child first and then the left. Then when you process the next level, the first node popped (i=0) is the rightmost node of that level. So this part is correct.

  4. But: You are not handling the case when the node is null. You should only process non-null nodes. So in the inner loop, you should check if the node is not null before accessing its value and children.

  5. Revised Approach: Here's how you can fix your code:

    • Check if root is null at the start and return an empty list.
    • Initialize the queue with root.
    • In the while loop, for each level, the first node you pop (which is the rightmost node of that level) should be added to the result. But note: you are already doing that with if i==0: result.append(node.val). However, you must ensure that the node is not null. But in your queue, you are only adding non-null nodes? Actually, you are adding children without checking for null. So you need to change that.
  6. How to fix:

    • When adding children, only add if they are not null.
    • Also, the root might be null, so handle that.

Here is a corrected version of your code:

from collections import deque

class Solution:
    def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        
        result = []
        levelQueue = deque([root])
        
        while levelQueue:
            level_size = len(levelQueue)
            for i in range(level_size):
                node = levelQueue.popleft()
                # If it's the last node in the current level, add to result
                if i == level_size - 1:
                    result.append(node.val)
                # Add left and right children if they exist
                if node.left:
                    levelQueue.append(node.left)
                if node.right:
                    levelQueue.append(node.right)
                    
        return result

Wait, note: the above corrected code uses the last node in the level (i == level_size-1) instead of the first. Why? Because in a standard BFS where we add left first and then right, the last node in the level will be the rightmost. Alternatively, if you add right first and then left, the first node would be the rightmost. So both approaches are valid.

But your original code used the first node (i=0) and added right first then left. That is correct. However, you did not handle null nodes. So the corrected code for your approach would be:

from collections import deque

class Solution:
    def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        
        result = []
        queue = deque([root])
        
        while queue:
            level_size = len(queue)
            for i in range(level_size):
                node = queue.popleft()
                if i == 0:
                    result.append(node.val)
                # Add right child first, then left
                if node.right:
                    queue.append(node.right)
                if node.left:
                    queue.append(node.left)
                    
        return result

This should work. But note: the common approach is to add left first and then right, and take the last node in the level. Your approach is valid too.

However, your original code did not check for null when adding children. So you must add those checks.

  1. Final Thoughts: Your code was close to being correct, but missed the null checks and the root null check. Always remember to handle edge cases. Also, make sure to test your code with the provided examples, especially the empty tree case.

VERDICT: NEEDS_IMPROVEMENT


Cousins in Tree (Problem2.py)

Strengths:

  • You are using BFS (level-order traversal) which is a good approach for this problem because we need to check depth.
  • The code is structured and readable.

Areas for Improvement:

  1. The solution does not correctly track the depth of the nodes. The flags foundCousingX and foundCousingY are set for children, but they are not reset at the beginning of each level. This means that if x is found in one level, the flag remains true for all subsequent levels, which leads to incorrect results.
  2. The solution does not check the parent of the nodes. For cousins, we need to ensure that the parents are different. Your code checks for siblings (same parent) and returns false correctly if they are siblings, but it does not check if the nodes are at the same depth with different parents. The current approach might return true for nodes that are at the same depth but not cousins (e.g., if they are siblings? Actually you check for siblings and return false, which is good, but the depth check is flawed).
  3. The root node is not considered: if x or y is the root, it will never be found because you only check children. The root has no parent, so it cannot have a cousin. But note: the problem states that the number of nodes is at least 2 and x and y are different and exist. So the root might be one of them? Actually, if the root is x, then it has depth 0. The only way for it to have a cousin is if there is another node at depth 0? But there isn't. So if x is root, it has no cousin. But your code never checks the root node. You start by appending the root, but then in the loop you only check the children. So if x is the root, it will never be detected. Similarly, if the root has children, you check them, but the root itself is not checked.

How to fix:

  • You need to check each node in the queue for being x or y. Currently, you are only checking the children of the node when you iterate. Instead, you should check the current node when you pop it from the queue.
  • You should track the parent of each node. One common way is to store the parent along with the node in the queue. Alternatively, you can store tuples (node, parent) in the queue.
  • You should reset the flags for x and y at the start of each level. Then, when processing a level, if you find both x and y, you can check if they have different parents. If they do, return true. If only one is found in a level, return false because they are not at the same depth.

Revised approach:

  • Use a queue that stores (node, parent) for each node.
  • For each level, initialize two variables: foundX = false, foundY = false, and parentX = None, parentY = None.
  • Process all nodes in the current level. For each node, if it is x, set foundX = true and record its parent. Similarly for y.
  • After processing the entire level, if both foundX and foundY are true, then check if parentX != parentY -> return true.
  • If only one is found, return false because they are not at the same depth.
  • If none are found, continue to the next level.

Example code structure:

q = deque([(root, None)])
while q:
    n = len(q)
    foundX = False
    foundY = False
    parentX = None
    parentY = None
    for _ in range(n):
        node, parent = q.popleft()
        if node.val == x:
            foundX = True
            parentX = parent
        if node.val == y:
            foundY = True
            parentY = parent
        if node.left:
            q.append((node.left, node))
        if node.right:
            q.append((node.right, node))
    if foundX and foundY:
        return parentX != parentY
    if foundX or foundY:
        return False
return False

VERDICT: NEEDS_IMPROVEMENT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants