7.108. 将有序数组转换为二叉搜索树
给你一个整数数组 nums
,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
示例 1:
输入:nums = [-10,-3,0,5,9] 输出:[0,-3,9,-10,null,5] 解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:示例 2:
输入:nums = [1,3] 输出:[3,1] 解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。提示:
1 <= nums.length <= 10^4
-10^4 <= nums[i] <= 10^4
nums
按 严格递增 顺序排列
思路:
因为是按照升序递增,最好的方法就是按照二分的方式,以中间元素为跟节点,依次进行建树。
代码:
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution {public TreeNode sortedArrayToBST(int[] nums) {return dfs(nums, 0, nums.length - 1);}private TreeNode dfs(int[] nums, int lo, int hi) {if (lo > hi) {return null;} // 以升序数组的中间元素作为根节点 root。int mid = lo + (hi - lo) / 2;TreeNode root = new TreeNode(nums[mid]);// 递归的构建 root 的左子树与右子树。root.left = dfs(nums, lo, mid - 1);root.right = dfs(nums, mid + 1, hi); return root;}
}
8.98. 验证二叉搜索树
给你一个二叉树的根节点 root
,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:root = [2,1,3] 输出:true示例 2:
输入:root = [5,1,4,null,null,3,6] 输出:false 解释:根节点的值是 5 ,但是右子节点的值是 4 。提示:
- 树中节点数目范围在
[1, 104]
内-2^31 <= Node.val <= 2^31 - 1
思路:
刚开始还想着中序遍历输出元素至列表,然后对列表进行判断,如果其不是升序,则返回false。
其实没必要,直接中序遍历进行判断即可!保存一个全局变量,用于保存上一个访问到的节点。
代码:
用列表存一下再判断:
class Solution {
private:vector<int> vec;void traversal(TreeNode* root) {if (root == NULL) return;traversal(root->left);vec.push_back(root->val); // 将二叉搜索树转换为有序数组traversal(root->right);}
public:bool isValidBST(TreeNode* root) {vec.clear(); // 不加这句在leetcode上也可以过,但最好加上traversal(root);for (int i = 1; i < vec.size(); i++) {// 注意要小于等于,搜索树里不能有相同元素if (vec[i] <= vec[i - 1]) return false;}return true;}
};
不用列表:
class Solution:def isValidBST(self, root: TreeNode) -> bool:# 规律: BST的中序遍历节点数值是从小到大. cur_max = -float("INF")def __isValidBST(root: TreeNode) -> bool: nonlocal cur_maxif not root: return Trueis_left_valid = __isValidBST(root.left)if cur_max < root.val: cur_max = root.valelse: return Falseis_right_valid = __isValidBST(root.right)return is_left_valid and is_right_validreturn __isValidBST(root)
9.230. 二叉搜索树中第K小的元素
给定一个二叉搜索树的根节点
root
,和一个整数k
,请你设计一个算法查找其中第k
个最小元素(从 1 开始计数)。示例 1:
输入:root = [3,1,4,null,2], k = 1 输出:1示例 2:
输入:root = [5,3,6,2,4,null,null,1], k = 3 输出:3提示:
- 树中的节点数为
n
。1 <= k <= n <= 10^4
0 <= Node.val <= 10^4
思路:
中序遍历,加上全局变量curnum,到k以后,直接输出。
代码:
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:int curnum=0;int dfs(TreeNode* root,int k){if(! root){return -1;}int x,y;x=dfs(root->left,k);curnum++;if(curnum==k)return root->val;y=dfs(root->right,k);if(x>=0)return x;if(y>=0)return y;return -1;}int kthSmallest(TreeNode* root, int k) {return dfs(root,k);}
};
python版,更简洁:
class Solution:def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:def dfs(root):if not root: returndfs(root.left)if self.k == 0: returnself.k -= 1if self.k == 0: self.res = root.valdfs(root.right)self.k = kdfs(root)return self.res
10.199. 二叉树的右视图
给定一个二叉树的 根节点 root
,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例 1:
输入: [1,2,3,null,5,null,4] 输出: [1,3,4]示例 2:
输入: [1,null,3] 输出: [1,3]示例 3:
输入: [] 输出: []提示:
- 二叉树的节点个数的范围是
[0,100]
-100 <= Node.val <= 100
思路:
层序遍历,每一次输出本层最后一个节点。
代码:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:def rightSideView(self, root: Optional[TreeNode]) -> List[int]:res=[]if not root:return res que=[root]while que:new = []res.append([node.val for node in que][-1])for cur in que:if cur.left:new.append(cur.left)if cur.right:new.append(cur.right)que=newreturn res