树的创建一定是递归创建,分而治之的
刷题顺序遵循
https://blog.csdn.net/linhuanmars/article/details/41040087
1.LeetCode108,将有序数组转换为二叉搜索树
对于该题一个比较朴素的想法就是讲每棵树的左右子树的节点数量差控制在一个节点范围内,即每次将数组arr分成(arr-1)/2和arr-(arr-1)/2-1两个子树,然后数组中间节点作为根节点
def build(arr[],l,r):
if l>r:
return None
mid=l+(r-l)/2
root=TreeNode(arr[mid])
root.left=build(arr,l,mid-1)
root.right=build(arr,mid+1,r)
return root
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return build(nums,0,nums.length-1);
}
private TreeNode build(int[] nums,int l,int r){
if(l>r)
return null;
int mid=l+(r-l)/2;
TreeNode node=new TreeNode(nums[mid]);
node.left=build(nums,l,mid-1);
node.right=build(nums,mid+1,r);
return node;
}
}
Java与C++区别,写C++的数组一般用vector,Java里面直接用arr[],和 C很像,int[] arr
LeetCode109,将有序链表转换为二叉搜索树
同样的思路,将数组分成两部分,在进入链表前记录链表的长度n,将前n/2的元素放入左子树,第n/2+1作为当前节点,剩下的元素作为右子树,同时保证进入左右子树时元素大于0,否则赋值为0
TreeNode* build(ListNode* head,int n){
int i=0;
ListNode *cur=head;
while(i<n/2){
i++;
cur=cur->next;
}
TreeNode *cur_=new TreeNode(cur->val);
if(n/2>0)
cur_->left=build(head,n/2);
else
cur_->left=NULL;
if((n-n/2-1)>0)
cur_->right=build(cur->next,n-n/2-1);
else
cur_->right=NULL;
return cur_;
}
再补一块关于C++ new运算符,该运算符返回的是一个指针
//Allocates size bytes of storage, suitably aligned to represent any object of that size, and returns a non-null pointer to the first byte of this block.
LeetCode 105
从前序和中序序列中恢复二叉树
def buildTree(self, preorder, inorder):
"""
:type preorder: List[int]
:type inorder: List[int]
:rtype: TreeNode
"""
if len(preorder)==0:
return None
mid=0
for i in range(len(inorder)):
if inorder[i]==preorder[0]:
mid=i
root=TreeNode(preorder[0])
root.left=self.buildTree(preorder[1:mid+1],inorder[:mid])
root.right=self.buildTree(preorder[mid+1:],inorder[mid+1:])
return root
树的前序为根左右,中序为左根右,加上树的构造都是递归,所以我们的想法是将前序分成当前节点+左子树+右子树,中序分成左子树+当前节点+右子树,一个朴素 的想法是拿着根去中序中将树分隔开
def buildTree(self, preorder, inorder):
"""
:type preorder: List[int]
:type inorder: List[int]
:rtype: TreeNode
"""
if inorder:
root = TreeNode(preorder.pop(0))
ind = inorder.index(root.val)
root.left = self.buildTree(preorder,inorder[:ind])
root.right = self.buildTree(preorder,inorder[ind+1:])
return root
在力扣上看别人写的
list pop(index)方法,从list中删除下标为index的元素,并返回list[index]
list index() 函数用于从列表中找出某个值第一个匹配项的索引位置,则此时右子树可以被分隔开
此时还利用到python默认传引用的技巧,当左子树完全处理完时,所有左子树即可被pop完
LeetCode106
从中序和后序恢复二叉树
def buildTree(self, inorder, postorder):
"""
:type inorder: List[int]
:type postorder: List[int]
:rtype: TreeNode
"""
if inorder:
root=TreeNode(postorder.pop(-1))
index=inorder.index(root.val)
root.right=self.buildTree(inorder[index+1:],postorder)
root.left=self.buildTree(inorder[:index],postorder)
return root
类似的,只是这次是先构建右子树,后构建左子树,但是不要忘记判断中序是否为空