标题:得到bst的公共最近祖先节点
可以看看这个Java实现二叉搜索树的最近公共祖先节点
bst最近公共祖先节点
- 方法一:得到两个list,【通过bst的搜索直接得到list保存父节点的集合】,使用一个for循环important
- 方法二;通过bst的搜索特性,这个递归有点意思,
/**
* bst最近公共祖先节点
* 方法一:得到两个list,【通过bst的搜索直接得到list保存父节点的集合】,使用一个for循环important
* 方法二;通过bst的搜索特性,这个递归有点意思,
*
* @author dell
*
*/
public class TestCommonNode02 {
/*题目三
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
7 -》 6ms
*/
public TreeNode commonBstNode(TreeNode head, TreeNode p1, TreeNode p2){
/*
List<TreeNode> list1 = this.selectFaBstNodeToList(head, p1); //用两个list,和使用list、set差不多
Set<TreeNode> set = this.selectFaBstNodeToSet(head, p2);
for(int i = list1.size() - 1; i >= 0; i--){
if(set.contains(list1.get(i))){//.val要不要都可以
return list1.get(i);
}
}*/
List<TreeNode> list1 = this.selectFaBstNodeToList(head, p1);
List<TreeNode> list2 = this.selectFaBstNodeToList(head, p2);
//使用两个for循环写的
/*
执行用时:7 ms, 在所有 Java 提交中击败了38.56% 的用户
内存消耗:39.4 MB, 在所有 Java 提交中击败了87.30% 的用户
for(int i = list1.size() - 1; i >= 0; i--){
for(int j = 0; j < list2.size(); j++){
if(list1.get(i) == list2.get(j)){
return list1.get(i);
}
}
}
return null;
*/
//=》使用一层for循环
/*
执行结果:
通过
显示详情
执行用时:6 ms, 在所有 Java 提交中击败了99.93% 的用户
内存消耗:39.4 MB, 在所有 Java 提交中击败了88.09% 的用户
*/
TreeNode node = null;
for(int i = 0; i < list1.size() && i < list2.size(); i++){
if(list1.get(i) == list2.get(i)){
node = list1.get(i);
}else{
return node;
}
}
return node;
}
//返回p的父节点--》list
public List<TreeNode> selectFaBstNodeToList(TreeNode head,TreeNode p){
List<TreeNode> list = new ArrayList<>();
if(head == null){
if(p == null){
return list;
}
throw new RuntimeException("head 为null!!!");
}
TreeNode node = head;
while(node != null){
list.add(node);
if(p.val == node.val){
return list;
}else if(p.val < node.val){
node = node.left;
}else {
node = node.right;
}
}
return list;
}
//返回p的父节点--》set
public Set<TreeNode> selectFaBstNodeToSet(TreeNode head,TreeNode p){
Set<TreeNode> set = new HashSet<>();
if(head == null){
if(p == null){
return set;
}
throw new RuntimeException("head 为null!!!");
}
TreeNode node = head;
while(node != null){
set.add(node);
if(p.val == node.val){
return set;
}else if(p.val < node.val){
node = node.left;
}else {
node = node.right;
}
}
return set;
}
//方法二:
/*递归,利用bst的搜索快
1.使p1 < p2
2.如果p1/p2的value == head.val return head
3.如果一个小于head,一个大于head,return head
4.如果两个都小于,调用head.left
5.如果两个都大于,调用head.right
执行结果:
通过
显示详情
执行用时:6 ms, 在所有 Java 提交中击败了99.93% 的用户
内存消耗:39.5 MB, 在所有 Java 提交中击败了72.55% 的用户
*/
public TreeNode lowestCommonAncestor02(TreeNode head, TreeNode p1, TreeNode p2){
//确保p1.val < p2.val
if(p1.val > p2.val){
return this.lowestCommonAncestor02(head, p2, p1);
}
if(p1.val == head.val || p2.val == head.val){ //注意可能p1/p2就是head
return head;
}else if(p1.val < head.val && p2.val > head.val){
return head;
}else if(p2.val < head.val){
return this.lowestCommonAncestor02(head.left, p1, p2);
}else{
return this.lowestCommonAncestor02(head.right, p1, p2);
}
}
//=>
public TreeNode lowestCommonAncestor021(TreeNode head, TreeNode p1, TreeNode p2){
if(p1.val < head.val && p2.val < head.val){
return this.lowestCommonAncestor021(head.left, p1, p2);
}else if(p1.val > head.val && p2.val > head.val){
return this.lowestCommonAncestor021(head.right, p1, p2);
}else{
return head;
}
}
/*
方法二的非递归版 思想和上面一样
执行用时:7 ms, 在所有 Java 提交中击败了38.56% 的用户
内存消耗:39.1 MB, 在所有 Java 提交中击败了96.86% 的用户
*/
public TreeNode lowestCommonAncestor(TreeNode head, TreeNode p1, TreeNode p2){
//确保p1.val < p2.val
if(p1.val > p2.val){
return this.lowestCommonAncestor(head, p2, p1);
}
if(head == null){
return null;
}
TreeNode node = head;
while(node != null){
if(p1.val == node.val || p2.val == node.val){ //注意可能p1/p2就是head
return node;
}else if(p1.val < node.val && p2.val > node.val){
return node;
}else if(p2.val < node.val){
node = node.left;
}else{
node = node.right;
}
}
return null;
}
/**
* 初始化一个tree
* 类广度遍历
* @param a
* @return
*/
public TreeNode initTree(Integer[] a) {
if(a == null || a.length == 0) {
return null;
}
int t = 0;
TreeNode p = new TreeNode(a[t]); //至少有一个元素
Queue<TreeNode> q = new LinkedList<>();
q.offer(p);
while(!q.isEmpty()) {
TreeNode node = q.poll();
if(t + 1 == a.length) { //先判断数组中是否还有下一个元素
return p;
}else {
t++;
if(a[t] == null) { //若下一个元素为null,则不需要创建新的节点
node.left = null;
}else {
node.left = new TreeNode(a[t]);
q.offer(node.left);
}
}
if(t + 1 == a.length) {
return p;
}else {
t++;
if(a[t] != null){ //上面的简写,a[t] == null,不需要再赋值
node.right = new TreeNode(a[t]);
q.offer(node.right);
}
}
}
return p;
}
@Test
public void test() {
Integer[] a = new Integer[] {1, 2, 3, 4, 5, 9, 10, null, 6, 7, 8, null, null, null, 11};
TreeNode head = this.initTree(a);
TreeNode p1 = new TreeNode(9);
TreeNode p2 = new TreeNode(8);
}
}