赞
踩
给定一个有序整数数组,将其转换为一棵高度平衡的二叉搜索树。
原题:LeetCode 108. 将有序数组转换为二叉搜索树
我们可以使用递归的方法来构建二叉搜索树。每次递归,我们选择数组的中间元素作为根节点,然后将数组分为左右两部分,分别构建左子树和右子树。
class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } public class Solution { public TreeNode sortedArrayToBST(int[] nums) { if (nums == null || nums.length == 0) { return null; } return buildBST(nums, 0, nums.length - 1); } private TreeNode buildBST(int[] nums, int start, int end) { if (start > end) { return null; } int mid = (start + end) / 2; TreeNode root = new TreeNode(nums[mid]); root.left = buildBST(nums, start, mid - 1); root.right = buildBST(nums, mid + 1, end); return root; } }
说明:
TreeNode
是树节点的定义。sortedArrayToBST
方法是入口点,首先检查输入数组的有效性,然后调用buildBST
方法进行递归构建。buildBST
方法是递归构建二叉搜索树的核心。它首先找到中间索引mid
,然后创建根节点,并递归地为左半部分和右半部分构建子树。
#include <stdlib.h> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; struct TreeNode* buildBST(int* nums, int start, int end) { if (start > end) { return NULL; } int mid = (start + end) / 2; struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode)); root->val = nums[mid]; root->left = buildBST(nums, start, mid - 1); root->right = buildBST(nums, mid + 1, end); return root; } struct TreeNode* sortedArrayToBST(int* nums, int numsSize){ if (nums == NULL || numsSize == 0) { return NULL; } return buildBST(nums, 0, numsSize - 1); }
说明:
- 这里使用 C 语言标准库中的
malloc
来动态分配内存。- 其余逻辑与 Java 版本类似。
class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right class Solution: def sortedArrayToBST(self, nums: List[int]) -> TreeNode: if not nums: return None def buildBST(start, end): if start > end: return None mid = (start + end) // 2 root = TreeNode(nums[mid]) root.left = buildBST(start, mid - 1) root.right = buildBST(mid + 1, end) return root return buildBST(0, len(nums) - 1)
说明:
- 使用 Python 类来定义树节点。
sortedArrayToBST
方法是入口点,它定义了一个内部递归函数buildBST
来构建二叉搜索树。
package main type TreeNode struct { Val int Left *TreeNode Right*TreeNode } func sortedArrayToBST(nums []int) *TreeNode { if len(nums) == 0 { return nil } return buildBST(nums, 0, len(nums)-1) } func buildBST(nums []int, start, end int) *TreeNode { if start > end { return nil } mid := (start + end) / 2 root := &TreeNode{Val: nums[mid]} root.Left = buildBST(nums, start, mid-1) root.Right = buildBST(nums, mid+1, end) return root } func main() { // 示例用法 nums := []int{-10, -3, 0, 5, 9} root := sortedArrayToBST(nums) // 这里可以添加遍历树的代码来验证结果 }
说明:
- 使用 Go 语言的结构体来定义树节点。
sortedArrayToBST
方法是入口点,调用buildBST
方法来构建二叉搜索树。buildBST
方法是递归函数,用于构建二叉搜索树。
迭代法构建二叉搜索树(BST)通常不如递归方法直观,但可以通过维护一个栈来模拟递归过程。以下是迭代法构建BST的思路以及使用Python、Java、C++和JavaScript四种语言的实现,包括注释和代码说明。
class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int val) { this.val = val; } } public class Solution { public TreeNode sortedArrayToBST(int[] nums) { if (nums == null || nums.length == 0) return null; Deque<Object[]> stack = new ArrayDeque<>(); int start = 0, end = nums.length - 1; TreeNode root = new TreeNode(nums[(start + end) / 2]); stack.push(new Object[]{root, start, end}); while (!stack.isEmpty()) { Object[] curr = stack.poll(); TreeNode node = (TreeNode) curr[0]; int s = (int) curr[1], e = (int) curr[2]; int mid = s + (e - s) / 2; if (s < mid) { TreeNode leftChild = new TreeNode(nums[mid - 1]); node.left = leftChild; stack.push(new Object[]{leftChild, s, mid - 1}); } if (mid + 1 < e) { TreeNode rightChild = new TreeNode(nums[mid + 1]); node.right = rightChild; stack.push(new Object[]{rightChild, mid + 1, e}); } } return root; } }
class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def sortedArrayToBST(nums): if not nums: return None stack, start, end = [], 0, len(nums) - 1 root = TreeNode(nums[start + (end - start) // 2]) stack.append((root, start, end)) while stack: node, start, end = stack.pop() mid = (start + end) // 2 if start < mid: left_child = TreeNode(nums[mid - 1]) # 左子树的根(实际上是mid-1,因为mid是根) node.left = left_child stack.append((left_child, start, mid - 1)) if mid + 1 < end: right_child = TreeNode(nums[mid + 1]) # 右子树的根(实际上是mid+1) node.right = right_child stack.append((right_child, mid + 1, end)) return root # 示例 nums = [-10, -3, 0, 5, 9] root = sortedArrayToBST(nums) # 遍历BST的代码略
#include <stack> #include <vector> struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; TreeNode* sortedArrayToBST(std::vector<int>& nums) { if (nums.empty()) { return nullptr; } std::stack<std::pair<TreeNode*, std::pair<int, int>>> stk; int n = nums.size(); TreeNode* root = new TreeNode(nums[n / 2]); stk.push({root, {0, n - 1}}); while (!stk.empty()) { auto curr = stk.top(); stk.pop(); TreeNode* node = curr.first; int start = curr.second.first; int end = curr.second.second; int mid = start + (end - start) / 2; if (start < mid) { node->left = new TreeNode(nums[mid - 1]); // 左子树的根节点 stk.push({node->left, {start, mid - 1}}); } if (mid + 1 < end) { node->right = new TreeNode(nums[mid + 1]); // 右子树的根节点 stk.push({node->right, {mid + 1, end}}); } } return root; } // 示例用法 int main() { std::vector<int> nums = {-10, -3, 0, 5, 9}; TreeNode* root = sortedArrayToBST(nums); // 遍历BST的代码略 return 0; }
当然,以下是Go语言版本的实现,其中包含了代码注释和说明:
package main import ( "fmt" ) // TreeNode represents a node in a binary tree type TreeNode struct { Val int Left *TreeNode Right *TreeNode } // sortedArrayToBST converts a sorted array to a balanced binary search tree func sortedArrayToBST(nums []int) *TreeNode { if len(nums) == 0 { return nil } // 定义辅助函数来构建BST var helper func(start, end int) *TreeNode helper = func(start, end int) *TreeNode { if start > end { return nil } // 找到中间元素作为当前子树的根 mid := (start + end) / 2 root := &TreeNode{Val: nums[mid]} // 递归地构建左子树和右子树 root.Left = helper(start, mid-1) root.Right = helper(mid+1, end) return root } // 调用辅助函数从整个数组构建BST return helper(0, len(nums)-1) } // inorderTraversal performs in-order traversal of a binary tree func inorderTraversal(root *TreeNode) { if root == nil { return } inorderTraversal(root.Left) fmt.Println(root.Val) inorderTraversal(root.Right) } func main() { nums := []int{-10, -3, 0, 5, 9} root := sortedArrayToBST(nums) // 验证BST是否构建正确,进行中序遍历 inorderTraversal(root) }
代码说明:
TreeNode
结构体定义了一个二叉树的节点,包含一个整数值Val
和两个指向左右子节点的指针Left
和Right
。
sortedArrayToBST
函数接受一个排序数组nums
,并返回一个指向平衡二叉搜索树根的指针。该函数定义了一个内部辅助函数helper
,它递归地构建BST。在
helper
函数中,我们首先检查start
是否大于end
,如果是,则返回nil
表示没有节点可构建。然后,我们找到中间元素mid
作为当前子树的根,并创建对应的TreeNode
。接下来,我们递归地调用helper
来构建左子树和右子树,并将返回的根节点分别赋值给当前节点的Left
和Right
。
inorderTraversal
函数用于验证BST是否构建正确。它使用中序遍历的方式遍历BST,并打印出每个节点的值。由于BST的性质,中序遍历将得到一个升序的序列。在
main
函数中,我们创建了一个排序数组nums
,并调用sortedArrayToBST
来构建BST。然后,我们调用inorderTraversal
来遍历BST并打印其节点值。
对于上述四种语言的实现,它们的复杂度分析是相同的:
以下是对于两种构建平衡二叉搜索树(BST)的方式的总结,包括它们的优点、缺点、时间复杂度和空间复杂度,以及其他特点:
方式 | 优点 | 缺点 | 时间复杂度 | 空间复杂度 | 其他 |
---|---|---|---|---|---|
递归中值法 | 1. 代码简洁,逻辑清晰。 | 1. 在最坏情况下,递归调用栈可能会占用额外的 O(n) 空间。 | O(n) | 平均 O(log n),最坏 O(n) | 1. 易于理解和实现。 |
迭代栈方法 | 1. 避免了递归调用栈可能导致的空间问题。 | 1. 相比递归方法,代码可能略显复杂。 | O(n) | 平均 O(log n),最坏 O(n) | 1. 更节省空间,适合处理大数据集。 |
说明:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。