算法:树

Posted danfengw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法:树相关的知识,希望对你有一定的参考价值。

树的最大路径和

https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/
思路:
递归+遍历

最大路径和

按照一个树 比如【a,b,c】 实际是三选一问题:b+root 与c+root 或者 b+c+root
maxSum 用于更新最大和,treeMaxSum

 int maxSum= Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) 
        treeMaxSum(root);
        return maxSum;
    

    public int treeMaxSum(TreeNode root)
        if (root==null) return 0;
      int left=Math.max(0,treeMaxSum(root.left));
        int right=Math.max(0,treeMaxSum(root.right));
        int tempMax=Math.max(left,right);
        tempMax=Math.max(tempMax,left+right);
        maxSum= Math.max(maxSum,tempMax+root.val);
        return Math.max(left,right)+root.val;
    

根据前序 中序遍历结果还原二叉树

https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

思路:
遍历 + 递归

前序:根左右
中序:左根右
根据中序遍历 可以分出左子树与右子树, 记录根的下标记 rootIndex,左子树个数为rootIndex 前的个数leftNum,从而知道前序遍历中的start+leftNum+1开始是左子树,后面的全部是右子树。递归调用

public TreeNode buildTree(int[] preorder, int[] inorder) 
        return buildTree(preorder, 0, preorder.length , inorder, 0, inorder.length );
    

    public TreeNode buildTree(int[] preorder, int p_start, int p_end,
                              int[] inorder, int i_start, int i_end) 
        if (p_start == p_end) 
            return null;
        
        TreeNode treeNode = new TreeNode(preorder[p_start]);
        int rootIndex = 0;
        for (int i = i_start; i < i_end; i++) 
            if (inorder[i] == preorder[p_start]) 
                rootIndex = i;
            
        
        int leftNum = rootIndex - i_start;

        treeNode.left = buildTree(preorder, p_start+1, p_start +1+ leftNum , inorder, i_start, rootIndex );
        treeNode.right = buildTree(preorder, p_start +1+ leftNum, p_end, inorder, rootIndex + 1, i_end);
        return treeNode;
    

树按层遍历(BFS)

规律: 利用队列 ,看作图的遍历
扩展: 可以求深度

 public List<List<Integer>> levelOrder(TreeNode root) 
        List<List<Integer>> list = new ArrayList<>();
         if (root==null) return list;
        Deque<TreeNode> queue = new ArrayDeque<>();
        queue.add(root);
        while (!queue.isEmpty()) 
            int size = queue.size();
            List<Integer> levelResult = new ArrayList<>();
            for (int i = 0; i < size; i++) 
                TreeNode cur = queue.poll();
                levelResult.add(cur.val);
                if (cur.left != null) 
                    queue.add(cur.left);
                
                if (cur.right != null) 
                    queue.add(cur.right);
                
            
            list.add(levelResult);
        
        return list;
    

树按深度遍历

非递归,利用栈实现

//深度优先遍历
    List<TreeNode> treeList ;
    public List<TreeNode> dfs(TreeNode root) 
        treeList = new ArrayList<>();
        if(root==null) 
            return  null;
        

        Stack<TreeNode> myStack=new Stack<>();
        myStack.add(root);

        while(!myStack.isEmpty()) 
            TreeNode node=myStack.pop();    //弹出栈顶元素
            //System.out.print(node.value+" ");
            treeList.add(node);
            //向栈中先压入右子树,在压入左子树。这样出栈时,先出左子树再出右子树.也就是,先遍历左边,后遍历右边
            if(node.right!=null) 
                myStack.push(node.right);
            
            if(node.left!=null) 
                myStack.push(node.left);
            
        
        return treeList;
    

递归

 List<TreeNode> treeNodeList = new ArrayList<>();;
    public List<TreeNode> dfsRec(TreeNode root) 
        
        if (root == null) 
            return null;
        
        treeNodeList.add(root);
        //System.out.print(root.value+" ");
        dfsRec(root.left);
        dfsRec(root.right);
        return treeNodeList;
    

以上是关于算法:树的主要内容,如果未能解决你的问题,请参考以下文章

算法题-平衡二叉树

一天一道算法题---找到二叉树中最大的搜素二叉子树

每日算法题 | 剑指offer 二叉树专题 (16) 平衡二叉树

Java数据结构与算法解析——AVL树

[算法模版]树的重心和直径

leetcode 114二叉树转换成链表