Given a binary tree, find its maximum depth.
The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
Given a binary tree as follow:
1
/ \
2 3
/ \
4 5
The maximum depth is 3
.
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: The root of binary tree.
* @return: An integer
*/
int maxDepth(TreeNode *root) {
// write your code here
if (root == NULL) {
return 0;
}
return max(maxDepth(root->left), maxDepth(root->right)) + 1;
}
};
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.
Given a binary tree as follow:
1
/ \
2 3
/ \
4 5
The minimum depth is 2
.
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/*
* @param root: The root of binary tree
* @return: An integer
*/
int minDepth(TreeNode * root) {
// write your code here
if (root == NULL) {
return 0;
}
if (root->left == NULL) {
return minDepth(root->right) + 1;
} else if (root->right == NULL) {
return minDepth(root->left) + 1;
} else {
return min(minDepth(root->left), minDepth(root->right)) + 1;
}
}
};
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.
Given binary tree A = {3,9,20,#,#,15,7}
, B = {3,#,20,15,7}
A) 3 B) 3
/ \ \
9 20 20
/ \ / \
15 7 15 7
The binary tree A is a height-balanced binary tree, but B is not.
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/*
* @param root: The root of binary tree.
* @return: True if this Binary tree is Balanced, or false.
*/
bool isBalanced(TreeNode * root) {
// write your code here
int maxDepth = 0;
return isBalanced(root, maxDepth);
}
bool isBalanced(TreeNode * root, int & maxDepth) {
if (root == NULL) {
maxDepth = 0;
return true;
}
int leftdepth = 0;
int rightdepth = 0;
bool leftbalance = isBalanced(root->left, leftdepth);
bool rightbalance = isBalanced(root->right, rightdepth);
if (leftbalance == false || rightbalance == false) {
return false;
}
if (abs(leftdepth - rightdepth) > 1) {
return false;
}
maxDepth = max(leftdepth, rightdepth) + 1;
return true;
}
};
Given the root and two nodes in a Binary Tree. Find the lowest common ancestor(LCA) of the two nodes.
The lowest common ancestor is the node with largest depth which is the ancestor of both nodes.
Notice
Assume two nodes are exist in tree.
For the following binary tree:
4
/ \
3 7
/ \
5 6
LCA(3, 5) = 4
LCA(5, 6) = 7
LCA(6, 7) = 7
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/*
* @param root: The root of the binary search tree.
* @param A: A TreeNode in a Binary.
* @param B: A TreeNode in a Binary.
* @return: Return the least common ancestor(LCA) of the two nodes.
*/
TreeNode * lowestCommonAncestor(TreeNode * root, TreeNode * A, TreeNode * B) {
// write your code here
TreeNode * ancestor = NULL;
int matchcount = lowestCommonAncestor2(root, A, B, ancestor);
return ancestor;
}
TreeNode * lowestCommonAncestor1(TreeNode * root, TreeNode * A, TreeNode * B) {
// write your code here
if (root == NULL || root == A || root == B) {
return root;
}
TreeNode* leftnode = lowestCommonAncestor(root->left, A, B);
TreeNode* rightnode = lowestCommonAncestor(root->right, A, B);
if (leftnode != NULL && rightnode != NULL) {
return root;
} else if (leftnode != NULL) {
return leftnode;
} else {
return rightnode;
}
}
int lowestCommonAncestor2(TreeNode * root, TreeNode * A, TreeNode * B, TreeNode * &ancestor) {
// write your code here
if (root == NULL) {
return 0;
}
int leftnode = lowestCommonAncestor2(root->left, A, B, ancestor);
if (ancestor != NULL) {
return 2;
}
int rightnode = lowestCommonAncestor2(root->right, A, B, ancestor);
if (ancestor != NULL) {
return 2;
}
if (leftnode + rightnode == 2) {
ancestor = root;
return 2;
}
if (root == A || root == B) {
if (leftnode + rightnode + 1 == 2) {
ancestor = root;
return 2;
} else {
return 1;
}
} else {
return leftnode + rightnode;
}
}
};
Given a binary tree, find the maximum path sum.
The path may start and end at any node in the tree.
Given the below binary tree:
1
/ \
2 3
return 6
.
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/*
* @param root: The root of binary tree.
* @return: An integer
*/
int maxPathSum(TreeNode * root) {
// write your code here
if (root == NULL) {
return 0;
}
int max_sum = INT_MIN;
maxPath(root, max_sum);
return max_sum;
}
int maxPath(TreeNode * root, int& max_sum) {
int left_value = 0;
if (root->left != NULL) {
left_value = maxPath(root->left, max_sum);
}
int right_value = 0;
if (root->right != NULL) {
right_value = maxPath(root->right, max_sum);
}
// compute max sum for this nodes
int cur_sum = 0;
int cur_max = 0;
if (left_value >= 0 && right_value >= 0) {
cur_max = max(left_value, right_value) + root->val;
cur_sum = left_value + right_value + root->val;
} else if (left_value >= 0) {
cur_max = left_value + root->val;
cur_sum = cur_max;
} else if (right_value >= 0) {
cur_max = right_value + root->val;
cur_sum = cur_max;
} else {
cur_max = root->val;
cur_sum = cur_max;
}
if (cur_sum > max_sum) {
max_sum = cur_sum;
}
return cur_max;
}
};
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.
- A single node tree is a BST
An example:
2
/ \
1 4
/ \
3 5
The above binary tree is serialized as {2,1,4,#,#,3,5}
(in level order).
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/*
* @param root: The root of binary tree.
* @return: True if the binary tree is BST, or false
*/
bool isValidBST(TreeNode * root) {
// write your code here
return isValidBST(root, LLONG_MAX, LLONG_MIN);
}
bool isValidBST(TreeNode * root, long long max_value, long long min_value) {
if (root == NULL) {
return true;
}
if (root->val < max_value && root->val > min_value) {
return isValidBST(root->left, root->val, min_value) && isValidBST(root->right, max_value, root->val);
} else {
return false;
}
}
};
Given a binary search tree and a new tree node, insert the node into the tree. You should keep the tree still be a valid binary search tree.
Notice
You can assume there is no duplicate values in this tree + node.
Given binary search tree as follow, after Insert node 6, the tree should be:
2 2
/ \ / \
1 4 --> 1 4
/ / \
3 3 6
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/*
* @param root: The root of the binary search tree.
* @param node: insert this node into the binary search tree
* @return: The root of the new binary search tree.
*/
TreeNode * insertNode(TreeNode * root, TreeNode * node) {
// write your code here
if (root == NULL) {
return node;
}
TreeNode * tmp = root;
while (true) {
if (tmp->val > node->val) {
if (tmp->left != NULL) {
tmp = tmp->left;
} else {
tmp->left = node;
break;
}
} else {
if (tmp->right != NULL) {
tmp = tmp->right;
} else {
tmp->right = node;
break;
}
}
}
return root;
}
};
Given a root of Binary Search Tree with unique value for each node. Remove the node with given value. If there is no such a node with given value in the binary search tree, do nothing. You should keep the tree still a binary search tree after removal.
Given binary search tree:
5
/ \
3 6
/ \
2 4
Remove 3, you can either return:
5
/ \
2 6
\
4
or
5
/ \
4 6
/
2
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/*
* @param root: The root of the binary search tree.
* @param value: Remove the node with given value.
* @return: The root of the binary search tree after removal.
*/
TreeNode * removeNode(TreeNode * root, int value) {
// write your code here
if (root == NULL) {
return NULL;
}
if (root->val == value) {
if (root->right != NULL) {
TreeNode* tmp = root->right;
while (tmp->left != NULL) {
tmp = tmp->left;
}
tmp->left = root->left;
return root->right;
} else {
return root->left;
}
} else {
root->left = removeNode(root->left, value);
root->right = removeNode(root->right, value);
return root;
}
}
};
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).
Given binary tree {3,9,20,#,#,15,7}
,
3 / \ 9 20 / \ 15 7
Challenge
Challenge 1: Using only 1 queue to implement it.
Challenge 2: Use DFS algorithm to do it.
return its level order traversal as:
[ [3], [9,20], [15,7] ]
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/*
* @param root: A Tree
* @return: Level order a list of lists of integer
*/
vector<vector<int>> levelOrder(TreeNode * root) {
// write your code here
vector<vector<int>> res;
if (root == NULL) {
return res;
}
queue<TreeNode*> qu;
qu.push(root);
int count = 1;
while (count > 0) {
vector<int> tmp;
while (count > 0) {
TreeNode* tn = qu.front();
qu.pop();
tmp.push_back(tn->val);
if (tn->left != NULL) {
qu.push(tn->left);
}
if (tn->right != NULL) {
qu.push(tn->right);
}
count--;
}
res.push_back(tmp);
count = qu.size();
}
return res;
}
};
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: A Tree
* @return: Level order a list of lists of integer
*/
vector<vector<int>> levelOrder(TreeNode * root) {
// write your code here
vector<vector<int>> res;
recursive(res, 0, root);
return res;
/*
if (root == NULL) {
return res;
}
// one queue
queue<TreeNode*> qu;
qu.push(root);
int count = 1;
while (!qu.empty()) {
int newcount = 0;
vector<int> result;
while (count-- > 0) {
TreeNode * node = qu.front();
qu.pop();
result.push_back(node->val);
// next line
if (node->left != NULL) {
qu.push(node->left);
newcount++;
}
if (node->right != NULL) {
qu.push(node->right);
newcount++;
}
}
res.push_back(result);
count = newcount;
}
*/
}
void recursive(vector<vector<int>> & res, int level, TreeNode * root) {
if (root == NULL) {
return;
}
// new line
if (res.size() <= level) {
// resize to ensure have enough space
vector<int> result;
result.reserve(1 << level);
res.push_back(result);
}
res[level].push_back(root->val);
// next line
recursive(res, level + 1, root->left);
recursive(res, level + 1, root->right);
}
};
Binary Tree Zigzag Level Order Traversal
Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).
Given binary tree {3,9,20,#,#,15,7}
,
3 / \ 9 20 / \ 15 7
return its zigzag level order traversal as:
[ [3], [20,9], [15,7] ]
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/*
* @param root: A Tree
* @return: A list of lists of integer include the zigzag level order traversal of its nodes' values.
*/
vector<vector<int>> zigzagLevelOrder(TreeNode * root) {
// write your code here
vector<vector<int>> res;
if (root == NULL) {
return res;
}
stack<TreeNode*> leftorder;
stack<TreeNode*> rightorder;
leftorder.push(root);
while (leftorder.size() > 0 || rightorder.size() > 0) {
if (leftorder.size() > 0) {
vector<int> tmp;
while (leftorder.size() > 0) {
TreeNode* tn = leftorder.top();
leftorder.pop();
tmp.push_back(tn->val);
if (tn->left != NULL) {
rightorder.push(tn->left);
}
if (tn->right != NULL) {
rightorder.push(tn->right);
}
}
res.push_back(tmp);
} else if (rightorder.size() > 0) {
vector<int> tmp;
while (rightorder.size() > 0) {
TreeNode* tn = rightorder.top();
rightorder.pop();
tmp.push_back(tn->val);
if (tn->right != NULL) {
leftorder.push(tn->right);
}
if (tn->left != NULL) {
leftorder.push(tn->left);
}
}
res.push_back(tmp);
}
}
return res;
}
};