• 力扣654题、105题、106题(二叉树、递归)


    654、寻找最大二叉树

    基本思想:

    构造二叉树,根节点要做的就是想办法把自己构造出来,

    先找到数组中的最大值,然后再用递归调用左右数组构造左右子树

    前序遍历

    具体实现:

    1.使用max函数找到数组中的最大值和对应的索引

    max_val = max(nums)

    max_idx = nums.index(max_val)

    2.最大值为二叉树根节点

    root = TreeNode(nums[max_idx])

    3.递归调用构造左右子树

    root.left = self.constructMaximumBinaryTree(nums[:max_idx])
    root.right = self.constructMaximumBinaryTree(nums[max_idx+1:])

    代码:

    class Solution {
        public TreeNode constructMaximumBinaryTree(int[] nums) {
            return constructMaximumBinaryTree1(nums, 0, nums.length);
        }
    
        public TreeNode constructMaximumBinaryTree1(int[] nums, int leftIndex, int rightIndex) {
            if (rightIndex - leftIndex < 1) {// 没有元素了
                return null;
            }
            if (rightIndex - leftIndex == 1) {// 只有一个元素
                return new TreeNode(nums[leftIndex]);
            }
            int maxIndex = leftIndex;// 最大值所在位置
            int maxVal = nums[maxIndex];// 最大值
            for (int i = leftIndex + 1; i < rightIndex; i++) {
                if (nums[i] > maxVal){
                    maxVal = nums[i];
                    maxIndex = i;
                }
            }
            TreeNode root = new TreeNode(maxVal);
            // 根据maxIndex划分左右子树
            root.left = constructMaximumBinaryTree1(nums, leftIndex, maxIndex);
            root.right = constructMaximumBinaryTree1(nums, maxIndex + 1, rightIndex);
            return root;
        }
    }

     105、从前序和中序遍历结果构造二叉树

    基本思想:

    确定根节点的值,把根节点确定出来,然后递归构造左右子树

    具体实现:

    1.找到根节点

    前序遍历第一个值为根节点

    root=TreeNode(preorder[0])

    根节点在中序遍历中的位置为切割点

    mid=inorder.index(preorder[0])

    2.切割

    切割前序数组,切成前序左数组和前序右数组

    切割中序数组,切成中序左数组和中序右数组

    3.递归构建左右子树

    代码:

    class Solution {
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            return helper(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
        }
    
        public TreeNode helper(int[] preorder, int preLeft, int preRight,
                               int[] inorder, int inLeft, int inRight) {
            // 递归终止条件
            if (inLeft > inRight || preLeft > preRight) return null;
    
            // val 为前序遍历第一个的值,也即是根节点的值
            // idx 为根据根节点的值来找中序遍历的下标
            int idx = inLeft, val = preorder[preLeft];
            TreeNode root = new TreeNode(val);
            for (int i = inLeft; i <= inRight; i++) {
                if (inorder[i] == val) {
                    idx = i;
                    break;
                }
            }
    
            // 根据 idx 来递归找左右子树
            root.left = helper(preorder, preLeft + 1, preLeft + (idx - inLeft),
                             inorder, inLeft, idx - 1);
            root.right = helper(preorder, preLeft + (idx - inLeft) + 1, preRight,
                             inorder, idx + 1, inRight);
            return root;
        }
    }

    106、从后序和中序遍历结果构造二叉树

     同上题

    class Solution {
        public TreeNode buildTree(int[] inorder, int[] postorder) {
            return buildTree1(inorder, 0, inorder.length, postorder, 0, postorder.length);
        }
        public TreeNode buildTree1(int[] inorder, int inLeft, int inRight,
                                   int[] postorder, int postLeft, int postRight) {
            // 没有元素了
            if (inRight - inLeft < 1) {
                return null;
            }
            // 只有一个元素了
            if (inRight - inLeft == 1) {
                return new TreeNode(inorder[inLeft]);
            }
            // 后序数组postorder里最后一个即为根结点
            int rootVal = postorder[postRight - 1];
            TreeNode root = new TreeNode(rootVal);
            int rootIndex = 0;
            // 根据根结点的值找到该值在中序数组inorder里的位置
            for (int i = inLeft; i < inRight; i++) {
                if (inorder[i] == rootVal) {
                    rootIndex = i;
                    break;
                }
            }
            // 根据rootIndex划分左右子树
            root.left = buildTree1(inorder, inLeft, rootIndex,
                    postorder, postLeft, postLeft + (rootIndex - inLeft));
            root.right = buildTree1(inorder, rootIndex + 1, inRight,
                    postorder, postLeft + (rootIndex - inLeft), postRight - 1);
            return root;
        }
    }

     

  • 相关阅读:
    如何调试在OJ中的代码
    在linux命令行中调试在OJ上的c++代码
    jar包
    stanford core
    decode encode
    访问服务器,远程访问linux主机
    代码18
    删除列表中的元素
    if __name__ == '__main__'
    苹果要求全部新app以及版本号更新必须支持iOS 8 SDK和64-bit
  • 原文地址:https://www.cnblogs.com/zhaojiayu/p/14050854.html
Copyright © 2020-2023  润新知