LeetCode::Tree(Part1)
98. Validate Binary Search Tree
Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
- The left subtree of a node contains only nodes with keys less than the node’s key.
- The right subtree of a node contains only nodes with keys greater than the node’s key.
- Both the left and right subtrees must also be binary search trees.
Wrong solution:
bool isValidBST(struct TreeNode* root) {
if (!root)
return true;
else if (root->left && (root->val <= root->left->val))
return false;
else if (root->right &&(root->val >= root->right->val))
return false;
else
return isValidBST(root->left)&&isValidBST(root->right);
}
5
/ \
1 4
/ \
3 6
Correct But Slow Solution
Solution 1 (Recursive)
bool _isValidBST(struct TreeNode* root, int min, int max){
if (root == NULL)
return true;
else if (root->val >= max || root->val <= min)
return false;
else
return _isValidBST(root->left, min, root->val) &&
_isValidBST(root->right, root->val, max);
}
bool isValidBST(struct TreeNode* root){
return _isValidBST(root, INT_MIN, INT_MAX);
}
Solution 2
in order traversal
100. Same Tree
Given two binary trees, write a function to check if they are the same or not.
Solution
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
if (p==NULL || q==NULL)
return q == q;
else
return (p->val == q->val) &&
isSameTree(p->left, q->left) &&
isSameTree(p->right, q->right);
}
101. Symmetric Tree
Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
For example, this binary tree [1,2,2,3,4,4,3]
is symmetric:
1
/ \
2 2
/ \ / \
3 4 4 3
Solution
bool isMirror(struct TreeNode* p, struct TreeNode* q){
if (p==NULL || q==NULL)
return p == q;
else
return (p->val == q->val) &&
isMirror(p->left, q->right) &&
isMirror(p->right, q->left);
}
bool isSymmetric(struct TreeNode* root){
if (!root)
return true;
else
return isMirror(root->left, root->right);
}
94. Binary Tree Inorder Traversal
Given a binary tree, return the inorder traversal of its nodes’ values.
Solution 1
/**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
int* inorderTraversal(struct TreeNode* root, int* returnSize) {
if (!root){
*returnSize = 0;
return NULL;
}
int leftSize, rightSize;
int* leftTree, *rightTree;
leftTree = inorderTraversal(root->left, &leftSize);
rightTree = inorderTraversal(root->right, &rightSize);
*returnSize = leftSize + rightSize + 1;
int* ans = malloc(sizeof(int)*(*returnSize));
if (leftTree)
memcpy(ans, leftTree, sizeof(int)*(leftSize));
ans[leftSize] = root->val;
if (rightTree)
memcpy(ans+(leftSize)+1, rightTree, sizeof(int)*(rightSize));
return ans;
}
110. Balanced Binary Tree
Given a binary tree, determine if it is height-balanced.
For this problem, a height-balanced binary tree is defined as: a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
Solution 1 (Slow)
def isBalanced(root):
if root is None:
return True
else:
return (abs(maxDepth(root.left) - maxDepth(root.right)) <=1 and
isBalanced(root.left) and
isBalanced(root.right))
def maxDepth(root):
if root is None:
return 0
else:
lenLeft = maxDepth(root.left)
lenRight = maxDepth(root.right)
return max(lenLeft, lenRight) + 1
Solution 2 (Global Variable)
def isBalanced(root):
Balanced = True
def dfs(self, root):
if root is None:
return 0
else:
left = dfs(root.left)
right = dfs(root.right)
if abs(left-right) > 1:
Balanced = False
return max(left, right) + 1
dfs(root)
return Balanced
Solution 3
def isBalanced(self, root):
def dfs(root):
if root is None:
return 0
left = dfs(root.left)
right = dfs(root.right)
if left == -1 or right == -1 or abs(left - right) > 1:
return -1
return max(left, right) + 1
return dfs(root) != -1
108. Convert Sorted Array to Binary Search Tree
Given an array where elements are sorted in ascending order, convert it to a height balanced BST.
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
Solution
struct TreeNode* sortedArrayToBST(int* nums, int numsSize){
if (numsSize == 0)
return NULL;
else if (numsSize == 1){
struct TreeNode* newNode = malloc(sizeof(struct TreeNode));
newNode->val = nums[0];
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
else{
int mid = numsSize/2;
struct TreeNode* newNode = malloc(sizeof(struct TreeNode));
newNode->val = nums[mid];
newNode->left = sortedArrayToBST(nums, mid);
newNode->right = sortedArrayToBST(nums+mid+1, numsSize-mid-1);
return newNode;
}
}
111. Minimum Depth of Binary Tree
Given a binary tree, find its minimum depth.
The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
Note: A leaf is a node with no children.
Wrong Solution
def minDepth(self, root: TreeNode) -> int:
if not root:
return 0
minLeft = self.minDepth(root.left)
minRight = self.minDepth(root.right)
return min(minLeft, minRight) + 1
Example: {1, 2} has minumum depth 2 If one of the subtree has depth 0, we need to get the other one.
Solution 1 (DFS)
def minDepth(root):
if not root:
return 0
minLeft = minDepth(root.left)
minRight = minDepth(root.right)
if minLeft == 0:
return minRight + 1
if minRight == 0:
return minLeft + 1
return min(minLeft, minRight) + 1
Solution 2 (BFS)
def minDepth(root):
if not root:
return 0
queue = collections.deque([(root, 1)])
while queue:
node, level = queue.popleft()
if not node.left and not node.right:
return level
if node.left:
queue.append((node.left, level+1))
if node.right:
queue.append((node.right, level+1))
Solution 3 (BFS without Queue)
For large tree, BFS could be faster
def minDepth(root):
if not root:
return 0
depth = 0
current_level = [root]
while current_level:
depth += 1
next_level = []
for node in current_level:
left = node.left
right = node.right
if not left and not right:
return depth
if left:
next_level.append(left)
if right:
next_level.append(right)
current_level = next_level
return depth