LeetCode 236 -- 二叉树的最近公共祖先 ( Lowest Common Ancestor of a Binary Tree ) ( C语言版 )

本文主要是介绍LeetCode 236 -- 二叉树的最近公共祖先 ( Lowest Common Ancestor of a Binary Tree ) ( C语言版 ),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述 : 

方法一:

代码如下(附有解析):

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/
struct TreeNode* FindNode(struct TreeNode* rootNode, struct TreeNode* Node) {if(rootNode==NULL)return NULL;if(rootNode==Node)return rootNode;struct TreeNode* ret=FindNode(rootNode->left,Node);if(ret){return ret;}return FindNode(rootNode->right,Node);
}
struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {if(root==p||root==q){return root;}bool pLeft,pRight,qLeft,qRight;//如果在左子树找到了,则将pLeft赋真,pRight赋假if(FindNode(root->left,p)){pLeft=true;pRight=false;}//如果在右子树找到了,则将pLeft赋假,pRight赋真else{pLeft=false;pRight=true;}//如果在左子树找到了,则将qLeft赋真,qRight赋假if(FindNode(root->right,q)){qLeft=false;qRight=true;}//如果在右子树找到了,则将qLeft赋假,qRight赋真else{qLeft=true;qRight=false;}//若当前节点就为公共祖先,那么pq两个节点肯定一个在左子树,一个在右子树,if((pLeft&&qRight)||(pRight&&qLeft))return root;//如果pq都在左子树,则递归到左子树去找if(pLeft&&qLeft)return lowestCommonAncestor(root->left,p,q);//如果pq都在右子树,则递归到右子树去找elsereturn lowestCommonAncestor(root->right,p,q);
}

方法二:

解题思路 : 使用递归查找 , 如果有一个节点与根节点匹配 , 那么直接返回根节点 , 否则依次在左子树和右子树中查找 ,并且用left和right分别记录左子树的返回值和右子树的返回值 , 如果节点都存在左子树中 , 那么right就一定为NULL , 只需要返回 left , 如果节点都存在右子树中那么直接返回 right , 如果left和right都为空 返回NULL ;

代码如下 :

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/
struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {//如果找到p或q中任意一个直接返回if(root==NULL||root->val==p->val||root->val==q->val)return root;struct TreeNode* left=lowestCommonAncestor(root->left,p,q);struct TreeNode* right=lowestCommonAncestor(root->right,p,q);//左右节点都不为空返回根节点if(left&&right)return root;//左节点为空,返回右节点else if(left==NULL)return right;//右节点为空,返回左节点else if(right==NULL)return left;elsereturn NULL;
}

方法三:使用栈

代码如下:

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/typedef struct TreeNode*  DataType;typedef struct Stack
{DataType * _a;int _top;        //栈顶的位置int _capacity;   //栈的容量
}Stack;
typedef struct StackMin
{Stack s1;Stack s2;
}StackMin;
void StackInit(Stack *ps);
void StackDestroy(Stack *ps);
void StackPush(Stack *ps, DataType x);
void StackPop(Stack *ps);
DataType StackTop(Stack *ps);
int StackEmpty(Stack *ps);
int StackSize(Stack *ps);
void StackInit(Stack *ps)
{ps->_a = (DataType *)malloc(sizeof(DataType)* 3);	assert(ps->_a);    ps->_top = 0;ps->_capacity = 3;}
void StackDestroy(Stack *ps)
{assert(ps);free(ps->_a);ps->_a = NULL;ps->_capacity = 0;ps->_top = 0;
}
void StackPush(Stack *ps, DataType x)
{assert(ps);if (ps->_top >= ps->_capacity){ps->_a = (DataType*)realloc(ps->_a, sizeof(Stack)* (ps->_capacity*2));assert(ps->_a);ps->_capacity *= 2;}ps->_a[ps->_top] = x;ps->_top++;
}
void StackPop(Stack *ps)
{assert(ps->_top>0&&ps);ps->_top--;
}
DataType StackTop(Stack *ps)
{assert(ps);return ps->_a[ps->_top-1];
}
int StackEmpty(Stack *ps)
{assert(ps);return ps->_top == 0 ? 0 : 1;
}
int StackSize(Stack *ps)
{assert(ps);return ps->_top;
}
int GetPath(struct TreeNode* root,struct TreeNode* x,Stack *path){if(root==NULL)return 0;StackPush(path,root);if(root==x)return 1;if(GetPath(root->left,x,path)==1)return 1;if(GetPath(root->right,x,path)==1)return 1;StackPop(path);return 0;
}
struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {if(root==p||root==q){return root;}Stack pStack,qStack;StackInit(&pStack);StackInit(&qStack);GetPath(root,p,&pStack);GetPath(root,q,&qStack);while(StackSize(&pStack)!=StackSize(&qStack)){StackSize(&pStack)>StackSize(&qStack)?StackPop(&pStack):StackPop(&qStack);}while(StackTop(&pStack)!=StackTop(&qStack)){StackPop(&pStack);StackPop(&qStack);}struct TreeNode* ret=StackTop(&pStack);return ret;StackDestroy(&pStack);StackDestroy(&qStack);
}

 

这篇关于LeetCode 236 -- 二叉树的最近公共祖先 ( Lowest Common Ancestor of a Binary Tree ) ( C语言版 )的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/301024

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

poj1330(LCA最近公共祖先)

题意:求最近公共祖先 思路:之前学习了树链剖分,然后我就用树链剖分的一小部分知识就可以解这个题目了,记录每个结点的fa和depth。然后查找时,每次将depth大的结点往上走直到x = y。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring>

uva 575 Skew Binary(位运算)

求第一个以(2^(k+1)-1)为进制的数。 数据不大,可以直接搞。 代码: #include <stdio.h>#include <string.h>const int maxn = 100 + 5;int main(){char num[maxn];while (scanf("%s", num) == 1){if (num[0] == '0')break;int len =

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr