Skip to content

Add implementation for leetcode problems 199, 993#1595

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

Add implementation for leetcode problems 199, 993#1595
rishigoswamy wants to merge 1 commit intosuper30admin:masterfrom
rishigoswamy:master

Conversation

@rishigoswamy
Copy link
Copy Markdown

No description provided.

@super30admin
Copy link
Copy Markdown
Owner

Right Side View of a tree (leetcode_199.py)

Note: The verdict should be based on whether the student's solution is correct and efficient enough to pass the problem constraints.

IMPORTANT: The student has provided multiple implementations in their solution. You must evaluate the first one (the one that is not commented out) as the primary solution. The other commented implementations are alternatives that the student is considering, but you should focus on the first one.

Let's begin.

VERDICT: NEEDS_IMPROVEMENT


Cousins in Tree (leetcode_993.py)

Your approach of using BFS to traverse the tree level by level is correct in theory. However, there is a significant issue in your implementation: you do not reset the foundX, foundY, parentX, and parentY variables at the beginning of each level. Because these variables are declared outside the while loop, they retain their values across levels. This means that if you find x in one level and then in a later level you find y, the code will think both are found in the same level (which is not true) and then compare their parents. This will lead to false positives.

To fix this, you should reset these variables at the start of each level. Alternatively, you can structure your code like the reference solution: for each level, you process all nodes and check if either x or y is found. Then, at the end of the level, if both are found, you check if they have different parents. If only one is found, you return false immediately because they are at different depths.

Another issue is that you are only checking the children of the current node for x and y. This is correct because you are recording the parent when you check the children. However, note that the root is handled separately (which is good), but you are not checking the root's value again in the while loop? Actually, the root is added to the queue and then processed. But in the first iteration, the root is popped. Then you check its left and right children. So the root itself is never checked for being x or y? Actually, the root is already handled by the initial check: if root is x or y, return false. So that is correct.

But in the while loop, you are processing nodes and then only looking at their children. This means that the current node's value is never checked. However, the problem states that the root is at depth 0. So if x or y is the root, they have no parent and cannot be cousins with anyone. So your initial check is correct. But what if the root has value x and we are looking for x and y? Then we return false. But note: the root cannot be a cousin because it has no parent. So that is correct.

However, for other nodes, you are only checking the children. So if x is a child of a node, you record it. But if x is the current node? Actually, you are not checking the current node's value. This is a problem. For example, consider the root has left child with value x. Then when you process the root, you check its left child and set foundX to true and parentX to root. Then you add the left child to the queue. In the next level, you pop the left child (which is x). But you don't do anything with it? You only check its children. So if x has children, you check them. But you never check the current node's value. This is not an issue for x and y because you already found x when you were processing the root. But what if the node you are popping is y? You never check the value of the node you pop. So if y is in the current level and you pop it, you don't mark it as found. This is a critical flaw.

In your code, you are only detecting x and y when they are children of the current node. This means that if x or y is the root, you catch it in the initial check. For any other node, you only detect it when its parent is being processed. So if the tree has a node that is x, it will be detected when its parent is processed. This is correct because you are storing the parent. However, what if the node is x and it has no children? Then when you process the parent, you detect x and set foundX and parentX. Then you add x to the queue. But when you pop x from the queue, you don't check its value again. This is okay because you already detected it. So it works.

But wait: when you add a node to the queue, you are not storing any parent information for that node. So when you later pop it, you don't know who its parent is. However, you only need the parent when you detect x or y as a child. So your method is correct in that regard.

The main flaw is the lack of resetting the flags per level. You should move the declarations of foundX, foundY, parentX, and parentY inside the while loop, right after the size is taken. This way, they are reset for each level.

Also, you should note that the reference solution uses a separate queue to store the parent of each node. In your code, you are not storing the parent for each node in the queue. Instead, you are only recording the parent when you check the children. This is sufficient because you only need the parent when you find x or y.

But to fix your code, you need to reset the flags for each level. Here is how you can modify your code:

        while queue:
            foundX = False   # Reset for this level
            foundY = False
            parentX = None
            parentY = None
            size = len(queue)
            for i in range(size):
                node = queue.popleft()
                if node.left:
                    if node.left.val == x:
                        foundX = True
                        parentX = node
                    if node.left.val == y:
                        foundY = True
                        parentY = node
                    queue.append(node.left)
                if node.right:
                    if node.right.val == x:
                        foundX = True
                        parentX = node
                    if node.right.val == y:
                        foundY = True
                        parentY = node
                    queue.append(node.right)
            if foundX and foundY:
                return parentX != parentY
            if foundX or foundY:
                return False
        return False

This way, at the start of each level, the flags are reset. Then, after processing all nodes in the level, you check if both were found. If so, return whether parents are different. If only one was found, return false.

Also, note that the initial check for the root being x or y is correct. But what if both x and y are the root? Actually, the problem states x != y and they exist. So if the root is x, then y is not the root. So the initial check is sufficient.

Another corner case: if x and y are the same level but same parent? Then they are siblings,

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