Grand 169 question 第13题-108. 将有序数组转换为二叉搜索树

之前的题目视频在B站:@盘子ssa

第13题-108. 将有序数组转换为二叉搜索树

递归

二叉搜索树的中序遍历一定是有序的,也就是说,左子节点一定比当前节点小,右子节点一定比当前节点大。

所以,我们只需要每次选择nums[mid]作为当前节点的值,然后递归的让左节点选择左半边中间值,右节点选择右半边中间值即可。

构建时,构建的当前节点值为nums[mid],左节点值为nums[(left + mid - 1) / 2],右节点值为nums[(mid + 1 + right) / 2]。

由于是二分的遍历的数组,所以这样构建出来的二叉搜索树一定是高度平衡的。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left;
 *     public TreeNode right;
 *     public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
public class Solution {
    TreeNode Dfs(int[] nums, int left, int right) {
        if (left > right) {
            return null;
        }
        int mid = (left + right) / 2;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = Dfs(nums, left, mid - 1);
        root.right = Dfs(nums, mid + 1, right);
        return root;
    }

    public TreeNode SortedArrayToBST(int[] nums) {
        return Dfs(nums, 0, nums.Length - 1);
    }
}

队列模拟

显然,上述方法可以使用队列模拟。

递归函数传入参数有3个,但是nums是已知的,我们需要保存节点还有左右两个边界。

所以需要3个队列存储对应值,在模拟操作时,需要判断边界,当超出范围是,不应该再进行入队操作。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left;
 *     public TreeNode right;
 *     public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
public class Solution {
    TreeNode Dfs(int[] nums, int left, int right) {
        if (left > right) {
            return null;
        }
        int mid = (left + right) / 2;
        TreeNode root = new TreeNode(nums[mid]);
        root.left = Dfs(nums, left, mid - 1);
        root.right = Dfs(nums, mid + 1, right);
        return root;
    }

    public TreeNode SortedArrayToBST(int[] nums) {
        Queue<TreeNode> que = new Queue<TreeNode>();
        Queue<int> leftQue = new Queue<int>();
        Queue<int> rightQue = new Queue<int>();
        int mid = (0 + nums.Length - 1) / 2;
        que.Enqueue(new TreeNode(nums[mid]));
        TreeNode ans = que.Peek();
        leftQue.Enqueue(0);
        rightQue.Enqueue(nums.Length - 1);
        while (que.Count != 0) {
            TreeNode root = que.Dequeue();
            int left = leftQue.Dequeue();
            int right = rightQue.Dequeue();
            mid = (left + right) / 2;
            root.val = nums[mid];
            if (left <= mid - 1) {
                root.left = new TreeNode();
                que.Enqueue(root.left);
                leftQue.Enqueue(left);
                rightQue.Enqueue(mid - 1);
            }
            if (right >= mid + 1) {
                root.right = new TreeNode();
                que.Enqueue(root.right);
                leftQue.Enqueue(mid + 1);
                rightQue.Enqueue(right);
            }
        }
        return ans;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值