Grand 169 question
之前的题目视频在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;
}