Skip to content

Java Chapter 11: Trees #60

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Feb 1, 2025
40 changes: 40 additions & 0 deletions java/Trees/BalancedBinaryTreeValidation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import DS.TreeNode;

/*
// Definition of TreeNode:
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
*/

public class BalancedBinaryTreeValidation {
public boolean balancedBinaryTreeValidation(TreeNode root) {
return getHeightImbalance(root) != -1;
}

private int getHeightImbalance(TreeNode node) {
// Base case: if the node is null, its height is 0.
if (node == null) {
return 0;
}
// Recursively get the height of the left and right subtrees. If
// either subtree is imbalanced, propagate -1 up the tree.
int leftHeight = getHeightImbalance(node.left);
int rightHeight = getHeightImbalance(node.right);
if (leftHeight == -1 || rightHeight == -1) {
return -1;
}
// If the current node's subtree is imbalanced
// (height difference > 1), return -1.
if (Math.abs(leftHeight - rightHeight) > 1) {
return -1;
}
// Return the height of the current subtree.
return 1 + Math.max(leftHeight, rightHeight);
}
}
39 changes: 39 additions & 0 deletions java/Trees/BinarySearchTreeValidation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import DS.TreeNode;

/*
// Definition of TreeNode:
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
*/

public class BinarySearchTreeValidation {
public boolean binarySearchTreeValidation(TreeNode root) {
// Start validation at the root node. The root node can contain any
// value, so set the initial lower and upper bounds to null.
return isWithinBounds(root, null, null);
}

private boolean isWithinBounds(TreeNode node, Integer lowerBound, Integer upperBound) {
// Base case: if the node is null, it satisfies the BST condition.
if (node == null) {
return true;
}
// If the current node's value is not within the valid bounds, this
// tree is not a valid BST.
if (lowerBound != null && node.val <= lowerBound || upperBound != null && upperBound <= node.val) {
return false;
}
// If the left subtree isn't a BST, this tree isn't a BST.
if (!isWithinBounds(node.left, lowerBound, node.val)) {
return false;
}
// Otherwise, return true if the right subtree is also a BST.
return isWithinBounds(node.right, node.val, upperBound);
}
}
68 changes: 68 additions & 0 deletions java/Trees/BinaryTreeColumns.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;

import DS.TreeNode;

/*
// Definition of TreeNode:
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
*/

public class BinaryTreeColumns {
public class Pair {
TreeNode node;
int column;
public Pair(TreeNode node, int column) {
this.node = node;
this.column = column;
}
}

public List<List<Integer>> binaryTreeColumns(TreeNode root) {
if (root == null) {
return new ArrayList<>();
}
Map<Integer, List<Integer>> columnMap = new HashMap<>();
int leftmostColumn, rightmostColumn;
leftmostColumn = rightmostColumn = 0;
Queue<Pair> queue = new ArrayDeque<>();
queue.offer(new Pair(root, 0));
while (!queue.isEmpty()) {
Pair pair = queue.poll();
TreeNode node = pair.node;
int column = pair.column;
if (node != null) {
// Add the current node's value to its corresponding list in the hash
// map.
List<Integer> columnList = columnMap.getOrDefault(column, new ArrayList<>());
columnList.add(node.val);
columnMap.put(column, columnList);
leftmostColumn = Math.min(leftmostColumn, column);
rightmostColumn = Math.max(rightmostColumn, column);
// Add the current node's children to the queue with their respective
// column ids.
queue.offer(new Pair(node.left, column - 1));
queue.offer(new Pair(node.right, column + 1));
}
}
// Construct the output list by collecting values from each column in the hash
// map in the correct order.
List<List<Integer>> res = new ArrayList<>();
for (int i = leftmostColumn; i <= rightmostColumn; i++) {
List<Integer> column = columnMap.get(i);
res.add(column);
}
return res;
}
}
44 changes: 44 additions & 0 deletions java/Trees/BinaryTreeSymmetry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import DS.TreeNode;

/*
// Definition of TreeNode:
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
*/

public class BinaryTreeSymmetry {
public boolean binaryTreeSymmetry(TreeNode root) {
if (root == null) {
return true;
}
return compareTrees(root.left, root.right);
}

private boolean compareTrees(TreeNode node1, TreeNode node2) {
// Base case: if both nodes are null, they're symmetric.
if (node1 == null && node2 == null) {
return true;
}
// If one node is null and the other isn't, they aren't symmetric.
if (node1 == null || node2 == null) {
return false;
}
// If the values of the current nodes don't match, trees aren't symmetric.
if (node1.val != node2.val) {
return false;
}
// Compare the 'node1's left subtree with 'node2's right subtree. If these
// aren't symmetric, the whole tree is not symmetric.
if (!compareTrees(node1.left, node2.right)) {
return false;
}
// Compare the 'node1's right subtree with 'node2's left subtree.
return compareTrees(node1.right, node2.left);
}
}
50 changes: 50 additions & 0 deletions java/Trees/BuildBinaryTree.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import java.util.HashMap;
import java.util.Map;

import DS.TreeNode;

/*
// Definition of TreeNode:
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
*/

public class BuildBinaryTree {
int preorderIndex = 0;
Map<Integer, Integer> inorderIndexesMap = new HashMap<>();

public TreeNode buildBinaryTree(int[] preorder, int[] inorder) {
// Populate the hash map with the inorder values and their indexes.
for (int i = 0; i < inorder.length; i++) {
inorderIndexesMap.put(inorder[i], i);
}
// Build the tree and return its root node.
return buildSubtree(0, inorder.length - 1, preorder, inorder);
}

private TreeNode buildSubtree(int left, int right, int[] preorder, int[] inorder) {
// Base case: if no elements are in this range, return None.
if (left > right) {
return null;
}
int val = preorder[preorderIndex];
// Set 'inorderIndex' to the index of the same value pointed at by
// 'preorderIndex'.
int inorderIndex = inorderIndexesMap.get(val);
TreeNode node = new TreeNode(val);
// Advance 'preorderIndex' so it points to the value of the next
// node to be created.
preorderIndex++;
// Build the left and right subtrees and connect them to the current
// node.
node.left = buildSubtree(left, inorderIndex - 1, preorder, inorder);
node.right = buildSubtree(inorderIndex + 1, right, preorder, inorder);
return node;
}
}
40 changes: 40 additions & 0 deletions java/Trees/InvertBinaryTreeIterative.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import java.util.Stack;

import DS.TreeNode;

/*
// Definition of TreeNode:
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
*/

public class InvertBinaryTreeIterative {
public TreeNode invertBinaryTreeIterative(TreeNode root) {
if (root == null) {
return null;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
// Swap the left and right subtrees of the current node.
TreeNode tmp = node.left;
node.left = node.right;
node.right = tmp;
// Push the left and right subtrees onto the stack.
if (node.left != null) {
stack.push(node.left);
}
if (node.right != null) {
stack.push(node.right);
}
}
return root;
}
}
30 changes: 30 additions & 0 deletions java/Trees/InvertBinaryTreeRecursive.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import DS.TreeNode;

/*
// Definition of TreeNode:
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
*/

public class InvertBinaryTreeRecursive {
public TreeNode invertBinaryTreeRecursive(TreeNode root) {
// Base case: If the node is null, there's nothing to invert.
if (root == null) {
return root;
}
// Swap the left and right subtrees of the current node.
TreeNode tmp = root.left;
root.left = root.right;
root.right = tmp;
// Recursively invert the left and right subtrees.
invertBinaryTreeRecursive(root.left);
invertBinaryTreeRecursive(root.right);
return root;
}
}
41 changes: 41 additions & 0 deletions java/Trees/KthSmallestNumberInBSTIterative.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import java.util.Stack;

import DS.TreeNode;

/*
// Definition of TreeNode:
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
*/

public class KthSmallestNumberInBSTIterative {
public int kthSmallestNumberInBSTIterative(TreeNode root, int k) {
Stack<TreeNode> stack = new Stack<>();
TreeNode node = root;
while (!stack.isEmpty() || node != null) {
// Move to the leftmost node and add nodes to the stack as we go so they
// can be processed in future iterations.
while (node != null) {
stack.push(node);
node = node.left;
}
// Pop the top node from the stack to process it, and decrement 'k'.
node = stack.pop();
k--;
// If we have processed 'k' nodes, return the value of the 'k'th smallest
// node.
if (k == 0) {
return node.val;
}
// Move to the right subtree.
node = node.right;
}
return -1;
}
}
34 changes: 34 additions & 0 deletions java/Trees/KthSmallestNumberInBSTRecursive.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import java.util.ArrayList;
import java.util.List;

import DS.TreeNode;

/*
// Definition of TreeNode:
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
*/

public class KthSmallestNumberInBSTRecursive {
public int kthSmallestNumberInBSTRecursive(TreeNode root, int k) {
List<Integer> sortedList = new ArrayList<>();
inorder(root, sortedList);
return sortedList.get(k - 1);
}

// Inorder traversal function to attain a sorted list of nodes from the BST.
private void inorder(TreeNode node, List<Integer> sortedList) {
if (node == null) {
return;
}
inorder(node.left, sortedList);
sortedList.add(node.val);
inorder(node.right, sortedList);
}
}
Loading