目录
本篇所有的代码已更新至码云仓库中,代码仓库地址:我的代码仓库
二叉树的最近公共祖先
题目链接:二叉树的最近公共祖先
题目描述:给定一棵二叉树,找到该树中两个指定结点的公共祖先.
例如:
解题思路:
1.首先判断该树是否为空,若为空直接返回null
2.判断给定的两个结点是否有为根结点的,若有,则直接返回根结点,根结点即这两个结点的公共祖先
3.分别递归遍历左子树和右子树,寻找其公共祖先,递归结束后判断保存的leftTree和rightTree:
①若leftTree和rightTree都为空,则其公共祖先为根节点;
②若leftTree为空,则p和q的公共祖先为rightTree;
③若rightTree为空,则p和q的公共祖先为leftTree.
具体实现代码如下:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) {
return null;
}
if(p == root || q == root) {
return root;
}
TreeNode leftTree = lowestCommonAncestor(root.left,p,q);
TreeNode rightTree = lowestCommonAncestor(root.right,p,q);
if(leftTree != null && rightTree != null) {
return root;
}
if(leftTree != null) {
return leftTree;
}else {
return rightTree;
}
}
二叉搜索树与双向链表
题目链接: 二叉搜索树与双向链表
题目描述: 输入一棵二叉搜索树,将二叉搜索树转换成一个双向的排序链表,具体如下图所示.
知识点回顾:什么是二叉搜索树?
二叉搜索树或是一棵空树,或是一棵具有如下性质的二叉树:若它的左子树不为空,则左子树上所有结点的值小于它的根结点值;若它的右子树不为空,则右子树上所有结点的值大于它的根结点值;它的左右子树分别也为二叉排序树.
解题思路:
为了方便代码的编写,采用了两个方法(Convert和ConvertChild方法)来实现转换操作
1、Convert方法的作用:
①判断该树是否为空,若为空直接返回null;
②在二叉搜索完成转换后寻找并返回双向链表的头结点.
2、ConvertChild方法的作用:
利用递归来实现二叉树对于双向链表的转换,转换完成后二叉搜索树的left代表着双向链表的前驱,right代表后驱.
①首先全局初始化一个结点prev用来完成每个的前驱链接;
②递归找到最后一个左子树,从该结点开始转换,转换的顺序依次为左、根、右;
具体的实现由递归完成,在方法中只思考如何转换:
无论是哪个结点,要进行转换必须将其left指向prev,再将prev.right指向该结点,具体实现思路可以了解下列代码
具体代码实现如下:
public TreeNode prev = null;
public void ConvertChild(TreeNode pCur) {
if(pCur == null) {
return;
}
ConvertChild(pCur.left);
pCur.left = prev;
if(prev != null) {
prev.right = pCur;
}
prev = pCur;
ConvertChild(pCur.right);
}
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree == null) {
return null;
}
ConvertChild(pRootOfTree);
TreeNode head = pRootOfTree;
while(head.left != null) {
head = head.left;
}
return head;
}
从前序和中序遍历序列构造二叉树
题目链接:从前序和中序遍历遍历序列构造二叉树
题目描述: 给定两个整数数组preorder和inorder,其中preorder表示的二叉树的先序遍历,inorder表示的二叉树的先序遍历,请构造二叉树并返回其根结点.
例如
解题思路:
首先了解前序遍历的顺序:根->左->右,中序遍历的顺序:左->根->右,根据两种遍历的思想初步确定实现思想:根据分治思想来解决该题
① 根据前序遍历可以知道根结点就是给定数组的第一个元素preorder[0],然后根据中序遍历在inorder数组中找到值等于preorder[0]的位置,该位置的前半部分即为左子树,右半部分为右子树;
② 重复“①”操作直到遍历完.
具体代码实现如下:
public int prevIndex = 0;
public int findIndex(int[] preorder,int[] inorder,int begin,int end) {
for(int i = begin; i<= end; i++) {
if(inorder[i] == preorder[prevIndex]) {
return i;
}
}
return -1;
}
public TreeNode buildTreeChild(int[] preorder,int[] inorder,int begin,int end) {
if(begin > end) {
return null;
}
TreeNode root = new TreeNode(preorder[prevIndex]);
int index = findIndex(preorder,inorder,begin,end);
prevIndex++;
root.left = buildTreeChild(preorder,inorder,begin,index-1);
root.right = buildTreeChild(preorder,inorder,index+1,end);
return root;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
return buildTreeChild(preorder,inorder,0,inorder.length-1);
}
根据二叉树创建字符串
题目链接:根据二叉树创建字符串
题目描述:你需要采取前序遍历的方式,将一棵二叉树转换成一个由括号和整数构成的字符串。
空结点由一对空括号"()"表示.
例如:
解题思路:
利用StringBuilder类来完成二叉树对字符串的转换,在转换完成后将其转换为String类型返回.
根据题意需要完成下列判断:
1、根据前序遍历顺序:根左右,首先判断根,若root不为null,首先将根结点利用append方法转换成字符串;
2、其次判断其左子树:
①若根结点左子树不为空,根据题意先加入'(',之后递归遍历其左子树,遍历完成后加上')';
②若根结点左子树为空:
如果其右子树也为空,则直接返回;若不为空,则根据题意加上'()',之后继续遍历其右子树.
3、最后判断其右子树:
①若右子树为空,直接返回;
②若不为空,则首先加入'(',之后对其右子树依次进行遍历,最终加上')'.
经过递归上述过程,即可实现二叉树对于字符串的转换
具体代码实现如下:
public void tree2strChild(TreeNode t, StringBuilder sb) {
if(t == null) {
return;
}
sb.append(t.val);
if(t.left != null) {
sb.append("(");
tree2strChild(t.left,sb);
sb.append(")");
}else {
if(t.right == null) {
return;
}else {
sb.append("()");
}
}
if(t.right == null) {
return;
}else {
sb.append("(");
tree2strChild(t.right,sb);
sb.append(")");
}
}
public String tree2str(TreeNode root) {
StringBuilder sb = new StringBuilder();
if(root == null) {
return sb.toString();
}
tree2strChild(root, sb);
return new String(sb);
}