Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions leetcode_199.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Mar 15 00:00:00 2026

@author: rishigoswamy

LeetCode 199: Binary Tree Right Side View
Link: https://leetcode.com/problems/binary-tree-right-side-view/

Problem:
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.

Approach:
DFS traversing root → right → left. The first node encountered at each depth is
the rightmost node visible from that level. Append to result only when visiting
a depth for the first time (len(result) == height).

1️⃣ If len(self.result) == height, this is the first node seen at this depth → append.
2️⃣ Recurse right first, then left.

// Time Complexity : O(n)
Every node is visited once.
// Space Complexity : O(h)
Recursive call stack depth equals the height of the tree.

"""

from collections import deque
from typing import List, Optional

# 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 rightSideView(self, root: Optional[TreeNode]) -> List[int]:
# DFS root → right → left; keep the first value seen at each level.
# Because right subtree is traversed first, the first value at each depth
# is always the rightmost visible node.
self.result = []

def dfs(node, height):
if not node:
return

if len(self.result) == height:
self.result.append(node.val)

dfs(node.right, height + 1)
dfs(node.left, height + 1)

dfs(root, 0)
return self.result

'''
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
# At each level pop the queue completely and keep the last value.
# While popping only pop till the current size, since children will also be added.
if not root:
return []
queue = deque()
queue.append(root)
result = []

while queue:
size = len(queue)
lastVal = None
for i in range(size):
node = queue.popleft()
lastVal = node.val

if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(lastVal)

return result
'''

'''
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
# None delimiter approach: collect full levels, then take last value of each.
if not root:
return []

queue = deque()
queue.append(root)
queue.append(None)
res = []
level = []

while len(queue) > 1:
node = queue.popleft()

if not node:
res.append(level)
level = []
queue.append(None)
else:
level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(level)

return [row[-1] for row in res]
'''

'''
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
# DFS root → left → right; keep updating the value at each level.
# Because left subtree is traversed first, right subtree overwrites any
# earlier value at the same depth, leaving the rightmost node.
self.result = []

def dfs(node, height):
if not node:
return

if len(self.result) <= height:
self.result.append(node.val)
else:
self.result[height] = node.val

dfs(node.left, height + 1)
dfs(node.right, height + 1)

dfs(root, 0)
return self.result
'''
89 changes: 89 additions & 0 deletions leetcode_993.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Mar 15 00:00:00 2026

@author: rishigoswamy

LeetCode 993: Cousins in Binary Tree
Link: https://leetcode.com/problems/cousins-in-binary-tree/

Problem:
Two nodes of a binary tree are cousins if they have the same depth but
different parents. Given the root and two values x and y, return true if
they are cousins.

Approach:
BFS level-by-level. Track foundX, foundY, parentX, parentY within each level.
If both are found in the same level with different parents → cousins.
If only one is found in a level → cannot be cousins → False.

1️⃣ Early exit: if root is x or y, it has no parent → False.
2️⃣ BFS level by level using queue size snapshot.
3️⃣ For each node, check if its children are x or y; record parent.
4️⃣ After each level: if both found and parents differ → True.
5️⃣ If only one found in this level → False (different depths).

// Time Complexity : O(n)
Every node is visited once.
// Space Complexity : O(n)
Queue holds at most O(n) nodes at a level.

"""

from collections import deque
from typing import Optional

# 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 isCousins(self, root: Optional[TreeNode], x: int, y: int) -> bool:
if not root:
return False

foundX = False
foundY = False
parentX = None
parentY = None

if root.val == x or root.val == y:
return False

queue = deque()
queue.append(root)

while queue:
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:
if parentX == parentY:
return False
return True
if foundX or foundY:
return False

return False