Record the Tree topic algorithm problems.
0094. Binary Tree Inorder Traversal
Given a binary tree, return the inorder traversal of its nodes’ values.
Example:
Input: [1,null,2,3]
Output: [1,3,2]
Follow up: Recursive solution is trivial, could you do it iteratively?
solution 1:
1 | const inorderTraversal = (root, arr = []) => { |
Runtime: 52 ms
Memory Usage: 33.9 MB
solution 2:
1 | const inorderTraversal = (root) => { |
Runtime: 48 ms
Memory Usage: 33.9 MB
0098. 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.
Example 1:
Input: [2,1,3]
Output: true
Example 2:
Input: [5,1,4,null,null,3,6]
Output: false
Explanation: The root node’s value is 5 but its right child’s value is 4.
solution:
1 | const isValidBST = (root) => { |
Runtime: 64 ms
Memory Usage: 37.6 MB
0101. 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
But the following [1,2,2,null,3,null,3] is not
solution 1:
1 | /* |
Time complexity is O(n), and space complexity is O(1)
Runtime: 64 ms
Memory Usage: 35.6 MB
solution 2:
1 |
|
Time complexity is still O(n), and space complexity is the height of the tree.
Runtime: 64 ms
Memory Usage: 35.5 MB
solution 3:
1 |
|
Time complexity is O(n) and space complexity is the width of the tree.
Runtime: 68 ms
Memory Usage: 35.6 MB
0102. Binary Tree Level Order Traversal
Given a binary tree, return the level order traversal of its nodes’ values. (ie, from left to right, level by level).
For example:
Given binary tree [3,9,20,null,null,15,7],
return its level order traversal as:
[
[3],
[9,20],
[15,7]
]
solution:
1 | const levelOrder = (root) => { |
Runtime: 60 ms
Memory Usage: 35 MB
0104. Maximum Depth of Binary Tree
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.
Note: A leaf is a node with no children.
Example:
Given binary tree [3,9,20,null,null,15,7],
return its depth = 3.
solution:
1 |
|
Runtime: 52 ms
Memory Usage: 37.3 MB
0105. Construct Binary Tree from Preorder and Inorder Traversal
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
For example, given
preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
Return the following binary tree:
[3,9,20,null,null,15,7]
solution 1:
1 | const buildTree = (preorder, inorder) => { |
Runtime: 80 ms
Memory Usage: 36.2 MB
solution 2:
1 | const buildTree = (preorder, inorder) => { |
Runtime: 64 ms
Memory Usage: 36.3 MB
0108. 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.
Example:
Given the sorted array: [-10,-3,0,5,9],
One possible answer is: [0,-3,9,-10,null,5]
solution:
1 | const sortedArrayToBST = (nums) => { |
Runtime: 72 ms
Memory Usage: 37.6 MB
0114. Flatten Binary Tree to Linked List
Given a binary tree, flatten it to a linked list in-place.
For example, given the following tree:
[1,2,5,3,4,null,6]
The flattened tree should look like:
[1,null,2,null,3,null,4,null,5,null,6]
solution:
1 | const flatten = (root) => { |
Runtime: 60 ms
Memory Usage: 35.8 MB
0124. Binary Tree Maximum Path Sum
Given a non-empty binary tree, find the maximum path sum.
For this problem, a path is defined as any node sequence from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root.
Example 1:
Input: root = [1,2,3]
Output: 6
Example 2:
Input: root = [-10,9,20,null,null,15,7]
Output: 42
Constraints:
The number of nodes in the tree is in the range [0, 3 * 104].
-1000 <= Node.val <= 1000
solution1:
1 | const maxPathSum = (root) => { |
Runtime: 96 ms
Memory Usage: 48.3 MB
solution2:
1 | const maxPathSum = (root) => { |
Runtime: 100 ms
Memory Usage: 48.2 MB
0226. Invert Binary Tree
Example:
Input:
[4,2,7,1,3,6,9]
Output:
[4,7,2,9,6,3,1]
solution 1:
1 |
|
Runtime: 60 ms
Memory Usage: 33.9 MB
solution 2:
1 |
|
Runtime: 56 ms
Memory Usage: 33.8 MB
solution 3:
1 |
|
Runtime: 56 ms
Memory Usage: 33.8 MB
0230. Kth Smallest Element in a BST
Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.
Example 1:
Input: root = [3,1,4,null,2], k = 1
3
/
1 4
2
Output: 1
Example 2:
Input: root = [5,3,6,2,4,null,null,1], k = 3
5
/
3 6
/
2 4
/
1
Output: 3
Follow up:
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?
Constraints:
The number of elements of the BST is between 1 to 10^4.
You may assume k is always valid, 1 ≤ k ≤ BST’s total elements.
solution:
1 | const kthSmallest = (root, k) => { |
Runtime: 84 ms
Memory Usage: 44.2 MB
0236. Lowest Common Ancestor of a Binary Tree
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.
Example 2:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
solution 1:
1 | const lowestCommonAncestor = (root, p, q) => { |
Runtime: 88 ms
Memory Usage: 41.5 MB
solution 2:
1 | const lowestCommonAncestor = (root, p, q) => { |
Runtime: 64 ms
Memory Usage: 41.6 MB
0297. Serialize and Deserialize Binary Tree
Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.
Clarification: The input/output format is the same as how LeetCode serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.
Example 1:
Input: root = [1,2,3,null,null,4,5]
Output: [1,2,3,null,null,4,5]
Example 2:
Input: root = []
Output: []
Example 3:
Input: root = [1]
Output: [1]
Example 4:
Input: root = [1,2]
Output: [1,2]
Constraints:
The number of nodes in the tree is in the range [0, 104].
-1000 <= Node.val <= 1000
solution1:
1 | const serialize = (root) => { |
Runtime: 164 ms
Memory Usage: 49.3 MB
solution2:
1 | const serialize = (root) => { |
Runtime: 128 ms
Memory Usage: 49.8 MB
0337. House Robber III
The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the “root.” Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that “all houses in this place forms a binary tree”. It will automatically contact the police if two directly-linked houses were broken into on the same night.
Determine the maximum amount of money the thief can rob tonight without alerting the police.
Example 1:
Input: [3,2,3,null,3,null,1]
Output: 7
Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
Example 2:
Input: [3,4,5,1,3,null,1]
Output: 9
Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9.
solution:
1 | const rob = (root) => { |
Runtime: 68 ms
Memory Usage: 38.2 MB
0437. Path Sum III
You are given a binary tree in which each node contains an integer value.
Find the number of paths that sum to a given value.
The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).
The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.
Example:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
Return 3. The paths that sum to 8 are:
- 5 -> 3
- 5 -> 2 -> 1
- -3 -> 11
solution:
1 | const pathSum = (root, sum, presums = { '0': 1 }, prev = 0) => { |
Runtime: 68 ms
Memory Usage: 38.4 MB
0543. Diameter of Binary Tree
Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root.
Example:
Given a binary tree [1,2,3,4,5]
Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3].
Note: The length of path between two nodes is represented by the number of edges between them.
solution:
1 | const diameterOfBinaryTree = (root) => { |
Runtime: 68 ms
Memory Usage: 37.1 MB
0617. Merge Two Binary Trees
Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not.
You need to merge them into a new binary tree. The merge rule is that if two nodes overlap, then sum node values up as the new value of the merged node. Otherwise, the NOT null node will be used as the node of new tree.
Example 1:
Input
[1,3,2,5][2,1,3,null,4,null,7]
Output
[3,4,5,5,4,null,7]
solution:
1 | const mergeTrees = (t1, t2) => { |
Runtime: 92 ms
Memory Usage: 40.6 MB