Skip to content

Commit 729224f

Browse files
authored
Merge pull request #60 from Jer3myYu/java-solutions-trees
Java Chapter 11: Trees
2 parents 54ee678 + 0ba5b3d commit 729224f

14 files changed

+638
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import DS.TreeNode;
2+
3+
/*
4+
// Definition of TreeNode:
5+
class TreeNode {
6+
public int val;
7+
public TreeNode left;
8+
public TreeNode right;
9+
public TreeNode(int val) {
10+
this.val = val;
11+
}
12+
}
13+
*/
14+
15+
public class BalancedBinaryTreeValidation {
16+
public boolean balancedBinaryTreeValidation(TreeNode root) {
17+
return getHeightImbalance(root) != -1;
18+
}
19+
20+
private int getHeightImbalance(TreeNode node) {
21+
// Base case: if the node is null, its height is 0.
22+
if (node == null) {
23+
return 0;
24+
}
25+
// Recursively get the height of the left and right subtrees. If
26+
// either subtree is imbalanced, propagate -1 up the tree.
27+
int leftHeight = getHeightImbalance(node.left);
28+
int rightHeight = getHeightImbalance(node.right);
29+
if (leftHeight == -1 || rightHeight == -1) {
30+
return -1;
31+
}
32+
// If the current node's subtree is imbalanced
33+
// (height difference > 1), return -1.
34+
if (Math.abs(leftHeight - rightHeight) > 1) {
35+
return -1;
36+
}
37+
// Return the height of the current subtree.
38+
return 1 + Math.max(leftHeight, rightHeight);
39+
}
40+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import DS.TreeNode;
2+
3+
/*
4+
// Definition of TreeNode:
5+
class TreeNode {
6+
public int val;
7+
public TreeNode left;
8+
public TreeNode right;
9+
public TreeNode(int val) {
10+
this.val = val;
11+
}
12+
}
13+
*/
14+
15+
public class BinarySearchTreeValidation {
16+
public boolean binarySearchTreeValidation(TreeNode root) {
17+
// Start validation at the root node. The root node can contain any
18+
// value, so set the initial lower and upper bounds to null.
19+
return isWithinBounds(root, null, null);
20+
}
21+
22+
private boolean isWithinBounds(TreeNode node, Integer lowerBound, Integer upperBound) {
23+
// Base case: if the node is null, it satisfies the BST condition.
24+
if (node == null) {
25+
return true;
26+
}
27+
// If the current node's value is not within the valid bounds, this
28+
// tree is not a valid BST.
29+
if (lowerBound != null && node.val <= lowerBound || upperBound != null && upperBound <= node.val) {
30+
return false;
31+
}
32+
// If the left subtree isn't a BST, this tree isn't a BST.
33+
if (!isWithinBounds(node.left, lowerBound, node.val)) {
34+
return false;
35+
}
36+
// Otherwise, return true if the right subtree is also a BST.
37+
return isWithinBounds(node.right, node.val, upperBound);
38+
}
39+
}

java/Trees/BinaryTreeColumns.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import java.util.ArrayDeque;
2+
import java.util.ArrayList;
3+
import java.util.HashMap;
4+
import java.util.List;
5+
import java.util.Map;
6+
import java.util.Queue;
7+
8+
import DS.TreeNode;
9+
10+
/*
11+
// Definition of TreeNode:
12+
class TreeNode {
13+
public int val;
14+
public TreeNode left;
15+
public TreeNode right;
16+
public TreeNode(int val) {
17+
this.val = val;
18+
}
19+
}
20+
*/
21+
22+
public class BinaryTreeColumns {
23+
public class Pair {
24+
TreeNode node;
25+
int column;
26+
public Pair(TreeNode node, int column) {
27+
this.node = node;
28+
this.column = column;
29+
}
30+
}
31+
32+
public List<List<Integer>> binaryTreeColumns(TreeNode root) {
33+
if (root == null) {
34+
return new ArrayList<>();
35+
}
36+
Map<Integer, List<Integer>> columnMap = new HashMap<>();
37+
int leftmostColumn, rightmostColumn;
38+
leftmostColumn = rightmostColumn = 0;
39+
Queue<Pair> queue = new ArrayDeque<>();
40+
queue.offer(new Pair(root, 0));
41+
while (!queue.isEmpty()) {
42+
Pair pair = queue.poll();
43+
TreeNode node = pair.node;
44+
int column = pair.column;
45+
if (node != null) {
46+
// Add the current node's value to its corresponding list in the hash
47+
// map.
48+
List<Integer> columnList = columnMap.getOrDefault(column, new ArrayList<>());
49+
columnList.add(node.val);
50+
columnMap.put(column, columnList);
51+
leftmostColumn = Math.min(leftmostColumn, column);
52+
rightmostColumn = Math.max(rightmostColumn, column);
53+
// Add the current node's children to the queue with their respective
54+
// column ids.
55+
queue.offer(new Pair(node.left, column - 1));
56+
queue.offer(new Pair(node.right, column + 1));
57+
}
58+
}
59+
// Construct the output list by collecting values from each column in the hash
60+
// map in the correct order.
61+
List<List<Integer>> res = new ArrayList<>();
62+
for (int i = leftmostColumn; i <= rightmostColumn; i++) {
63+
List<Integer> column = columnMap.get(i);
64+
res.add(column);
65+
}
66+
return res;
67+
}
68+
}

java/Trees/BinaryTreeSymmetry.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import DS.TreeNode;
2+
3+
/*
4+
// Definition of TreeNode:
5+
class TreeNode {
6+
public int val;
7+
public TreeNode left;
8+
public TreeNode right;
9+
public TreeNode(int val) {
10+
this.val = val;
11+
}
12+
}
13+
*/
14+
15+
public class BinaryTreeSymmetry {
16+
public boolean binaryTreeSymmetry(TreeNode root) {
17+
if (root == null) {
18+
return true;
19+
}
20+
return compareTrees(root.left, root.right);
21+
}
22+
23+
private boolean compareTrees(TreeNode node1, TreeNode node2) {
24+
// Base case: if both nodes are null, they're symmetric.
25+
if (node1 == null && node2 == null) {
26+
return true;
27+
}
28+
// If one node is null and the other isn't, they aren't symmetric.
29+
if (node1 == null || node2 == null) {
30+
return false;
31+
}
32+
// If the values of the current nodes don't match, trees aren't symmetric.
33+
if (node1.val != node2.val) {
34+
return false;
35+
}
36+
// Compare the 'node1's left subtree with 'node2's right subtree. If these
37+
// aren't symmetric, the whole tree is not symmetric.
38+
if (!compareTrees(node1.left, node2.right)) {
39+
return false;
40+
}
41+
// Compare the 'node1's right subtree with 'node2's left subtree.
42+
return compareTrees(node1.right, node2.left);
43+
}
44+
}

java/Trees/BuildBinaryTree.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import java.util.HashMap;
2+
import java.util.Map;
3+
4+
import DS.TreeNode;
5+
6+
/*
7+
// Definition of TreeNode:
8+
class TreeNode {
9+
public int val;
10+
public TreeNode left;
11+
public TreeNode right;
12+
public TreeNode(int val) {
13+
this.val = val;
14+
}
15+
}
16+
*/
17+
18+
public class BuildBinaryTree {
19+
int preorderIndex = 0;
20+
Map<Integer, Integer> inorderIndexesMap = new HashMap<>();
21+
22+
public TreeNode buildBinaryTree(int[] preorder, int[] inorder) {
23+
// Populate the hash map with the inorder values and their indexes.
24+
for (int i = 0; i < inorder.length; i++) {
25+
inorderIndexesMap.put(inorder[i], i);
26+
}
27+
// Build the tree and return its root node.
28+
return buildSubtree(0, inorder.length - 1, preorder, inorder);
29+
}
30+
31+
private TreeNode buildSubtree(int left, int right, int[] preorder, int[] inorder) {
32+
// Base case: if no elements are in this range, return None.
33+
if (left > right) {
34+
return null;
35+
}
36+
int val = preorder[preorderIndex];
37+
// Set 'inorderIndex' to the index of the same value pointed at by
38+
// 'preorderIndex'.
39+
int inorderIndex = inorderIndexesMap.get(val);
40+
TreeNode node = new TreeNode(val);
41+
// Advance 'preorderIndex' so it points to the value of the next
42+
// node to be created.
43+
preorderIndex++;
44+
// Build the left and right subtrees and connect them to the current
45+
// node.
46+
node.left = buildSubtree(left, inorderIndex - 1, preorder, inorder);
47+
node.right = buildSubtree(inorderIndex + 1, right, preorder, inorder);
48+
return node;
49+
}
50+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import java.util.Stack;
2+
3+
import DS.TreeNode;
4+
5+
/*
6+
// Definition of TreeNode:
7+
class TreeNode {
8+
public int val;
9+
public TreeNode left;
10+
public TreeNode right;
11+
public TreeNode(int val) {
12+
this.val = val;
13+
}
14+
}
15+
*/
16+
17+
public class InvertBinaryTreeIterative {
18+
public TreeNode invertBinaryTreeIterative(TreeNode root) {
19+
if (root == null) {
20+
return null;
21+
}
22+
Stack<TreeNode> stack = new Stack<>();
23+
stack.push(root);
24+
while (!stack.isEmpty()) {
25+
TreeNode node = stack.pop();
26+
// Swap the left and right subtrees of the current node.
27+
TreeNode tmp = node.left;
28+
node.left = node.right;
29+
node.right = tmp;
30+
// Push the left and right subtrees onto the stack.
31+
if (node.left != null) {
32+
stack.push(node.left);
33+
}
34+
if (node.right != null) {
35+
stack.push(node.right);
36+
}
37+
}
38+
return root;
39+
}
40+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import DS.TreeNode;
2+
3+
/*
4+
// Definition of TreeNode:
5+
class TreeNode {
6+
public int val;
7+
public TreeNode left;
8+
public TreeNode right;
9+
public TreeNode(int val) {
10+
this.val = val;
11+
}
12+
}
13+
*/
14+
15+
public class InvertBinaryTreeRecursive {
16+
public TreeNode invertBinaryTreeRecursive(TreeNode root) {
17+
// Base case: If the node is null, there's nothing to invert.
18+
if (root == null) {
19+
return root;
20+
}
21+
// Swap the left and right subtrees of the current node.
22+
TreeNode tmp = root.left;
23+
root.left = root.right;
24+
root.right = tmp;
25+
// Recursively invert the left and right subtrees.
26+
invertBinaryTreeRecursive(root.left);
27+
invertBinaryTreeRecursive(root.right);
28+
return root;
29+
}
30+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import java.util.Stack;
2+
3+
import DS.TreeNode;
4+
5+
/*
6+
// Definition of TreeNode:
7+
class TreeNode {
8+
public int val;
9+
public TreeNode left;
10+
public TreeNode right;
11+
public TreeNode(int val) {
12+
this.val = val;
13+
}
14+
}
15+
*/
16+
17+
public class KthSmallestNumberInBSTIterative {
18+
public int kthSmallestNumberInBSTIterative(TreeNode root, int k) {
19+
Stack<TreeNode> stack = new Stack<>();
20+
TreeNode node = root;
21+
while (!stack.isEmpty() || node != null) {
22+
// Move to the leftmost node and add nodes to the stack as we go so they
23+
// can be processed in future iterations.
24+
while (node != null) {
25+
stack.push(node);
26+
node = node.left;
27+
}
28+
// Pop the top node from the stack to process it, and decrement 'k'.
29+
node = stack.pop();
30+
k--;
31+
// If we have processed 'k' nodes, return the value of the 'k'th smallest
32+
// node.
33+
if (k == 0) {
34+
return node.val;
35+
}
36+
// Move to the right subtree.
37+
node = node.right;
38+
}
39+
return -1;
40+
}
41+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import java.util.ArrayList;
2+
import java.util.List;
3+
4+
import DS.TreeNode;
5+
6+
/*
7+
// Definition of TreeNode:
8+
class TreeNode {
9+
public int val;
10+
public TreeNode left;
11+
public TreeNode right;
12+
public TreeNode(int val) {
13+
this.val = val;
14+
}
15+
}
16+
*/
17+
18+
public class KthSmallestNumberInBSTRecursive {
19+
public int kthSmallestNumberInBSTRecursive(TreeNode root, int k) {
20+
List<Integer> sortedList = new ArrayList<>();
21+
inorder(root, sortedList);
22+
return sortedList.get(k - 1);
23+
}
24+
25+
// Inorder traversal function to attain a sorted list of nodes from the BST.
26+
private void inorder(TreeNode node, List<Integer> sortedList) {
27+
if (node == null) {
28+
return;
29+
}
30+
inorder(node.left, sortedList);
31+
sortedList.add(node.val);
32+
inorder(node.right, sortedList);
33+
}
34+
}

0 commit comments

Comments
 (0)