[LeetCode] 108. Convert Sorted Array to Binary Search Tree 把有序数组转成二叉搜索树
Given an array where elements are sorted in ascending order, convert it to a height balanced BST.
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
Example:
Given the sorted array: [-10,-3,0,5,9], One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST: 0 / \ -3 9 / / -10 5
给定一个升序排序的数组,把它转成一个高度平衡的二叉搜索树(两个子树的深度相差不大于1)。
二叉搜索树的特点:
1. 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
2. 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
3. 任意节点的左、右子树也分别为二叉查找树;
4. 没有键值相等的节点。
中序遍历二叉查找树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉查找树变成一个有序序列,构造树的过程即为对无序序列进行查找的过程。
反过来,根节点就是有序数组的中间点,从中间点分开为左右两个有序数组,再分别找出两个数组的中间点作为左右两个子节点,就是二分查找法。
解法1:二分法BS + 递归Recursive
解法2: 二分法 + 迭代
Java: Recursive
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public TreeNode sortedArrayToBST( int [] num) { if (num.length == 0 ) { return null ; } TreeNode head = helper(num, 0 , num.length - 1 ); return head; } public TreeNode helper( int [] num, int low, int high) { if (low > high) { // Done return null ; } int mid = (low + high) / 2 ; TreeNode node = new TreeNode(num[mid]); node.left = helper(num, low, mid - 1 ); node.right = helper(num, mid + 1 , high); return node; } |
Java: Iterative
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | public class Solution { public TreeNode sortedArrayToBST( int [] nums) { int len = nums.length; if ( len == 0 ) { return null ; } // 0 as a placeholder TreeNode head = new TreeNode( 0 ); Deque<TreeNode> nodeStack = new LinkedList<TreeNode>() {{ push(head); }}; Deque<Integer> leftIndexStack = new LinkedList<Integer>() {{ push( 0 ); }}; Deque<Integer> rightIndexStack = new LinkedList<Integer>() {{ push(len- 1 ); }}; while ( !nodeStack.isEmpty() ) { TreeNode currNode = nodeStack.pop(); int left = leftIndexStack.pop(); int right = rightIndexStack.pop(); int mid = left + (right-left)/ 2 ; // avoid overflow currNode.val = nums[mid]; if ( left <= mid- 1 ) { currNode.left = new TreeNode( 0 ); nodeStack.push(currNode.left); leftIndexStack.push(left); rightIndexStack.push(mid- 1 ); } if ( mid+ 1 <= right ) { currNode.right = new TreeNode( 0 ); nodeStack.push(currNode.right); leftIndexStack.push(mid+ 1 ); rightIndexStack.push(right); } } return head; } } |
Python:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | class Solution( object ): def sortedArrayToBST( self , nums): """ :type nums: List[int] :rtype: TreeNode """ return self .sortedArrayToBSTRecu(nums, 0 , len (nums)) def sortedArrayToBSTRecu( self , nums, start, end): if start = = end: return None mid = start + self .perfect_tree_pivot(end - start) node = TreeNode(nums[mid]) node.left = self .sortedArrayToBSTRecu(nums, start, mid) node.right = self .sortedArrayToBSTRecu(nums, mid + 1 , end) return node def perfect_tree_pivot( self , n): """ Find the point to partition n keys for a perfect binary search tree """ x = 1 # find a power of 2 <= n//2 # while x <= n//2: # this loop could probably be written more elegantly :) # x *= 2 x = 1 << (n.bit_length() - 1 ) # use the left bit shift, same as multiplying x by 2**n-1 if x / / 2 - 1 < = (n - x): return x - 1 # case 1: the left subtree of the root is perfect and the right subtree has less nodes else : return n - x / / 2 # case 2 == n - (x//2 - 1) - 1 : the left subtree of the root # has more nodes and the right subtree is perfect. |
C++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class Solution { public : TreeNode* sortedArrayToBST(vector< int >& nums) { return sortedArrayToBSTHelper(nums, 0, nums.size() - 1); } private : TreeNode *sortedArrayToBSTHelper(vector< int > &nums, int start, int end) { if (start <= end) { TreeNode *node = new TreeNode(nums[start + (end - start) / 2]); node->left = sortedArrayToBSTHelper(nums, start, start + (end - start) / 2 - 1); node->right = sortedArrayToBSTHelper(nums, start + (end - start) / 2 + 1, end); return node; } return nullptr ; } }; |
C++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public : TreeNode *sortedArrayToBST(vector< int > &num) { return sortedArrayToBST(num, 0 , num.size() - 1); } TreeNode *sortedArrayToBST(vector< int > &num, int left, int right) { if (left > right) return NULL; int mid = (left + right) / 2; TreeNode *cur = new TreeNode(num[mid]); cur->left = sortedArrayToBST(num, left, mid - 1); cur->right = sortedArrayToBST(num, mid + 1, right); return cur; } }; |
类似题目:
[LeetCode] 109. Convert Sorted List to Binary Search Tree 把有序链表转成二叉搜索树
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构