Skip to content

Add solution for the "Lowest Common Ancestor of a Binary Search Tree" problem with unit tests. - #26

Merged
kobukuro merged 2 commits into
mainfrom
feat/lowest-common-ancestor-of-a-binary-search-tree
Sep 15, 2025
Merged

kobukuro merged 2 commits into
mainfrom
feat/lowest-common-ancestor-of-a-binary-search-tree

Conversation

@kobukuro

Copy link
Copy Markdown
Owner

No description provided.

Copilot AI review requested due to automatic review settings September 15, 2025 00:08

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements a solution for the LeetCode problem 235 "Lowest Common Ancestor of a Binary Search Tree" along with comprehensive unit tests. The solution leverages the properties of Binary Search Trees to efficiently find the lowest common ancestor of two nodes.

  • Adds a recursive solution that uses BST properties to traverse only the necessary path
  • Includes comprehensive test coverage with three test cases covering different scenarios
  • Provides time and space complexity analysis in code comments

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
src/main/java/com/leetcode/easy/LowestCommonAncestorOfABinarySearchTree235.java Implements the main solution using recursive BST traversal
src/test/java/com/leetcode/easy/LowestCommonAncestorOfABinarySearchTree235Test.java Provides unit tests covering edge cases and example scenarios
src/LowestCommonAncestorOfaBinarySearchTree235.java Empty file that should be removed

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

TreeNode p = new TreeNode(2);
TreeNode q = new TreeNode(8);
TreeNode result = solution.lowestCommonAncestor(root, p, q);
assert result.val == 6;

Copilot AI Sep 15, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use JUnit assertions instead of Java assert statements. Replace with assertEquals(6, result.val) for better test failure messages and IDE integration.

Copilot uses AI. Check for mistakes.
TreeNode p = new TreeNode(2);
TreeNode q = new TreeNode(4);
TreeNode result = solution.lowestCommonAncestor(root, p, q);
assert result.val == 2;

Copilot AI Sep 15, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use JUnit assertions instead of Java assert statements. Replace with assertEquals(2, result.val) for better test failure messages and IDE integration.

Copilot uses AI. Check for mistakes.
TreeNode p = new TreeNode(2);
TreeNode q = new TreeNode(1);
TreeNode result = solution.lowestCommonAncestor(root, p, q);
assert result.val == 2;

Copilot AI Sep 15, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use JUnit assertions instead of Java assert statements. Replace with assertEquals(2, result.val) for better test failure messages and IDE integration.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +41
TreeNode root = new TreeNode(6,
new TreeNode(2, new TreeNode(0), new TreeNode(4, new TreeNode(3), new TreeNode(5))),
new TreeNode(8, new TreeNode(7), new TreeNode(9)));
TreeNode p = new TreeNode(2);
TreeNode q = new TreeNode(8);
TreeNode result = solution.lowestCommonAncestor(root, p, q);
assert result.val == 6;
}

@Test
void testLowestCommonAncestor_Example2() {
TreeNode root = new TreeNode(6,
new TreeNode(2, new TreeNode(0), new TreeNode(4, new TreeNode(3), new TreeNode(5))),
new TreeNode(8, new TreeNode(7), new TreeNode(9)));
TreeNode p = new TreeNode(2);
TreeNode q = new TreeNode(4);
TreeNode result = solution.lowestCommonAncestor(root, p, q);
assert result.val == 2;
}

@Test
void testLowestCommonAncestor_Example3() {
TreeNode root = new TreeNode(2, new TreeNode(1), null);
TreeNode p = new TreeNode(2);
TreeNode q = new TreeNode(1);

Copilot AI Sep 15, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test creates new TreeNode instances with only values, but the algorithm needs to work with actual nodes from the tree. The p and q nodes should reference the existing nodes in the tree structure, not new instances with the same values.

Suggested change
TreeNode root = new TreeNode(6,
new TreeNode(2, new TreeNode(0), new TreeNode(4, new TreeNode(3), new TreeNode(5))),
new TreeNode(8, new TreeNode(7), new TreeNode(9)));
TreeNode p = new TreeNode(2);
TreeNode q = new TreeNode(8);
TreeNode result = solution.lowestCommonAncestor(root, p, q);
assert result.val == 6;
}
@Test
void testLowestCommonAncestor_Example2() {
TreeNode root = new TreeNode(6,
new TreeNode(2, new TreeNode(0), new TreeNode(4, new TreeNode(3), new TreeNode(5))),
new TreeNode(8, new TreeNode(7), new TreeNode(9)));
TreeNode p = new TreeNode(2);
TreeNode q = new TreeNode(4);
TreeNode result = solution.lowestCommonAncestor(root, p, q);
assert result.val == 2;
}
@Test
void testLowestCommonAncestor_Example3() {
TreeNode root = new TreeNode(2, new TreeNode(1), null);
TreeNode p = new TreeNode(2);
TreeNode q = new TreeNode(1);
TreeNode node0 = new TreeNode(0);
TreeNode node3 = new TreeNode(3);
TreeNode node5 = new TreeNode(5);
TreeNode node4 = new TreeNode(4, node3, node5);
TreeNode node2 = new TreeNode(2, node0, node4);
TreeNode node7 = new TreeNode(7);
TreeNode node9 = new TreeNode(9);
TreeNode node8 = new TreeNode(8, node7, node9);
TreeNode root = new TreeNode(6, node2, node8);
TreeNode p = node2;
TreeNode q = node8;
TreeNode result = solution.lowestCommonAncestor(root, p, q);
assert result.val == 6;
}
@Test
void testLowestCommonAncestor_Example2() {
TreeNode node0 = new TreeNode(0);
TreeNode node3 = new TreeNode(3);
TreeNode node5 = new TreeNode(5);
TreeNode node4 = new TreeNode(4, node3, node5);
TreeNode node2 = new TreeNode(2, node0, node4);
TreeNode node7 = new TreeNode(7);
TreeNode node9 = new TreeNode(9);
TreeNode node8 = new TreeNode(8, node7, node9);
TreeNode root = new TreeNode(6, node2, node8);
TreeNode p = node2;
TreeNode q = node4;
TreeNode result = solution.lowestCommonAncestor(root, p, q);
assert result.val == 2;
}
@Test
void testLowestCommonAncestor_Example3() {
TreeNode node1 = new TreeNode(1);
TreeNode root = new TreeNode(2, node1, null);
TreeNode p = root;
TreeNode q = node1;

Copilot uses AI. Check for mistakes.
Comment on lines +31 to +32
TreeNode p = new TreeNode(2);
TreeNode q = new TreeNode(4);

Copilot AI Sep 15, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test creates new TreeNode instances with only values, but the algorithm needs to work with actual nodes from the tree. The p and q nodes should reference the existing nodes in the tree structure, not new instances with the same values.

Copilot uses AI. Check for mistakes.
Comment on lines +40 to +41
TreeNode p = new TreeNode(2);
TreeNode q = new TreeNode(1);

Copilot AI Sep 15, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test creates new TreeNode instances with only values, but the algorithm needs to work with actual nodes from the tree. The p and q nodes should reference the existing nodes in the tree structure, not new instances with the same values.

Copilot uses AI. Check for mistakes.
… to use assertEquals and direct node references.
@kobukuro
kobukuro requested a review from Copilot September 15, 2025 02:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +17 to +25
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (p.val > root.val && q.val > root.val) {
return this.lowestCommonAncestor(root.right, p, q);
}
if (p.val < root.val && q.val < root.val) {
return this.lowestCommonAncestor(root.left, p, q);
}
return root;
}

Copilot AI Sep 15, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method doesn't handle null values for root, p, or q parameters. If any of these are null, accessing .val will throw a NullPointerException. Consider adding null checks at the beginning of the method.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +22
return this.lowestCommonAncestor(root.right, p, q);
}
if (p.val < root.val && q.val < root.val) {
return this.lowestCommonAncestor(root.left, p, q);

Copilot AI Sep 15, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential NullPointerException if root.right is null. The method should check if root.right exists before making the recursive call.

Suggested change
return this.lowestCommonAncestor(root.right, p, q);
}
if (p.val < root.val && q.val < root.val) {
return this.lowestCommonAncestor(root.left, p, q);
if (root.right != null) {
return this.lowestCommonAncestor(root.right, p, q);
} else {
return null;
}
}
if (p.val < root.val && q.val < root.val) {
if (root.left != null) {
return this.lowestCommonAncestor(root.left, p, q);
} else {
return null;
}

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +22
return this.lowestCommonAncestor(root.right, p, q);
}
if (p.val < root.val && q.val < root.val) {
return this.lowestCommonAncestor(root.left, p, q);

Copilot AI Sep 15, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential NullPointerException if root.left is null. The method should check if root.left exists before making the recursive call.

Suggested change
return this.lowestCommonAncestor(root.right, p, q);
}
if (p.val < root.val && q.val < root.val) {
return this.lowestCommonAncestor(root.left, p, q);
if (root.right != null) {
return this.lowestCommonAncestor(root.right, p, q);
} else {
return null;
}
}
if (p.val < root.val && q.val < root.val) {
if (root.left != null) {
return this.lowestCommonAncestor(root.left, p, q);
} else {
return null;
}

Copilot uses AI. Check for mistakes.
@kobukuro
kobukuro merged commit 25c5bc5 into main Sep 15, 2025
1 check passed
@kobukuro
kobukuro deleted the feat/lowest-common-ancestor-of-a-binary-search-tree branch September 15, 2025 02:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants