LeetCode107.二叉树的层次遍历
题目:
给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
思路1:
不需要使用栈,通过链表的方式
res.add(0,list);//list表示对每层节点的处理
代码1:
public ArrayList<ArrayList<Integer>> levelOrderBottom(TreeNode root) {
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
ArrayList<TreeNode> list = new ArrayList<Integer>();
if(root ==null) return res;
list.add(root);
while(!list.isEmpty()) {
ArrayList<Integer> curList = new ArrayList<>();//遍历本层的节点,并逐一加入
ArrayList<TreeNode> nextList = new ArrayList<>();//添加子节点,用于下一层的遍历和获取下下层节点
//遍历list中的节点,对应一个层次的节点,如果有子节点,则按照从左投右加到nextList这个链表中
for(TreeNode cur:list) {
curList.add(cur.val);
if(cur.left!=null) nextList.add(cur.left);//下一层节点
if(cur.right!=null) nextList.add(cur.right);//下一层节点
}
list = nextList;//该层循环结束,开始处理下层循环
res.add(0,curList); //倒序插入链表
}
return res;
}
思路2:直接递归
类似:102
LeetCode106.中序遍历,后序构建二叉树
题目:
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
思路:
只能根据中序和前/后创建,因为中序可以切分左右子树
temp:后序遍历中最后一个节点(也即子树中的根节点)的索引
temp将inorder分成左[inStart,temp-1]和右[temp+1,inEnd]
temp将postorder分成
左:[pStart,pEnd-1-(inEnd-temp)];
右:[pEnd+temp-inEnd,pEnd-1] pS = pEnd-1-(inEnd-(temp+1))=pEnd+temp-inEnd;
代码:
public TreeNode buildTree(int[] inorder, int[] postorder) {
if(inorder==null||inorder.length==0||postorder==null||postorder.length==0||postorder.length!=inorder.length)
return null;
return helper(inorder,0,inorder.length-1,postorder,0,inorder.length-1);
}
private TreeNode helper(int[] inorder,int inStart,int inEnd,int[] postorder,int pStart,int pEnd) {
if(inStart<=inEnd && pStart<=pEnd) {
TreeNode cur = new TreeNode(postorder[pEnd]);
int temp =find(inorder,inStart,inEnd,postorder[pEnd]);
if(temp!=-1)
{
cur.left=helper(inorder,inStart,temp-1,postorder,pStart,pEnd-1-(inEnd-temp));
cur.right=helper(inorder,temp+1,inEnd,postorder,pStart+temp-inStart,pEnd-1);
}
return cur;
}
return null;
}
private int find(int[] inorder,int start,int end,int target ) {
for(int i=start;i<=end;++i) {
if(inorder[i]==target)
return i;
}
return -1;
}
LeetCode105.先序遍历构建二叉树
题目:
先序和中序构建二叉树
思路:
代码:
public TreeNode buildTree(int[] preorder, int[] inorder) {
return dfs(preorder,0,preorder.length,inorder,0);
}
private TreeNode dfs(int[] preorder,int preStart,int preEnd,int[] inorder,int inStart){
if(preEnd==0)
return null;
TreeNode cur = new TreeNode(preorder[preStart]);
int temp=0;
while(temp<preEnd){
if(inorder[temp+inStart]==preorder[preStart])
break;
temp++;
}
cur.left = dfs(preorder,preStart+1,temp,inorder,inStart);
cur.right = dfs(preorder,preStart+1+temp,preEnd-temp-1,inorder,inStart+temp+1);
return cur;
}
代码2:一模一样的思路,自己第二天写的,重新计算了下两个边界,加深印象
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder==null||inorder==null||preorder.length!=inorder.length)
return null;
return dfs(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
}
private TreeNode dfs(int[] preorder,int preStart,int preEnd,int[] inorder, int inStart,int inEnd) {
if(preStart<=preEnd&&inStart<=inEnd)
{
TreeNode cur = new TreeNode(preorder[preStart]);//根节点为先序序列的第一个数
int temp = find(inorder,inStart,inEnd,preorder[preStart]);
cur.left = dfs(preorder,preStart+1,preStart+temp-inStart,inorder,inStart,temp-1);
cur.right = dfs(preorder,preStart+temp-inStart+1,preEnd,inorder,temp+1,inEnd);
return cur;
}
return null;
}
private int find(int[] inorder,int inStart,int inEnd,int target) {
for(int i=inStart;i<=inEnd;++i)
if(inorder[i]==target)
return i;
return -1;
}