LeetCode题目:
- [654. 最大二叉树](#654. 最大二叉树)
- [617. 合并二叉树](#617. 合并二叉树)
- [700. 二叉搜索树中的搜索](#700. 二叉搜索树中的搜索)
- [98. 验证二叉搜索树](#98. 验证二叉搜索树)
- [2843. 统计对称整数的数目](#2843. 统计对称整数的数目)
其他:
654. 最大二叉树
跳转:
学习: 代码随想录公开讲解
问题:
给定一个不重复的整数数组 nums
。 最大二叉树 可以用下面的算法从 nums
递归地构建:
- 创建一个根节点,其值为
nums
中的最大值。 - 递归地在最大值 左边 的 子数组前缀上 构建左子树。
- 递归地在最大值 右边 的 子数组后缀上 构建右子树。

返回 nums
构建的 *最大二叉树* 。
思路:
这道题要求构造二叉树,使用前序遍历先构造自身再构造子树比较符合直觉,当然,先构造子节点再构造父节点后序遍历也是没有问题的,不过需要先存储子节点再构造父节点,比较麻烦.当然,用中序遍历也是,只需要先处理到左根,再创建节点,再绑定右子树即可.所以说前中后序只是创建节点的位置不同.
但这题用层序遍历就不是很合适,因为数组不是很好划分,要存储全部路径的边界状态.
因为需要获取两个子节点再操作本节点,所以使用迭代法比较麻烦.
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
代码(前序递归实现):
java
class Solution {
TreeNode getTree(int[] nums,int l,int r)
{
if(l>=r) return null;
if(r-l==1) return new TreeNode(nums[l]);
int index = l;
int max = 0;
for(int i=l;i<r;i++){
if(nums[i]>max){
max = nums[i];
index = i;
}
}
TreeNode root = new TreeNode(max);
root.left = getTree(nums,l,index);
root.right = getTree(nums,index+1,r);
return root;
}
public TreeNode constructMaximumBinaryTree(int[] nums) {
return getTree(nums,0,nums.length);
}
}
617. 合并二叉树
跳转:
学习: 代码随想录公开讲解
问题:
给你两棵二叉树: root1
和 root2
。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。

思路:
两棵树一起遍历,如果都不为null就合并,一方为null就返回另一方.
这里直接前序遍历
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( l o g n ) O(logn) O(logn)
代码:
java
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if(root1==null) return root2;
if(root2==null) return root1;
TreeNode root = new TreeNode(root1.val+root2.val);
root.left = mergeTrees(root1.left,root2.left);
root.right = mergeTrees(root1.right,root2.right);
return root;
}
}
700. 二叉搜索树中的搜索
跳转:
学习: 代码随想录公开讲解
问题:
给定二叉搜索树(BST)的根节点 root
和一个整数值 val
。
你需要在 BST 中找到节点值等于 val
的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null
。
思路:
这里直接利用二叉搜索树的性质选择递归方向即可
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( l o g n ) O(logn) O(logn)
代码:
java
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
if(root==null) return null;
if(root.val==val) return root;
if(root.val>val) return searchBST(root.left,val);
return searchBST(root.right,val);
}
}
98. 验证二叉搜索树
跳转:
学习: 代码随想录公开讲解
问题:
给你一个二叉树的根节点 root
,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
思路:
右子树中所有节点都大于当前节点,左子树中所有节点都小于当前节点,基于此,可以使用边界收缩法,判断子节点是否在边界内
当然,二叉搜索树有一个很重要的性质,那就是中序遍历下单调递增.所以如果能想到这条性质可以降低编码复杂度,并提升代码效率.
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
代码(中序遍历):
java
class Solution {
long pre = Long.MIN_VALUE;
public boolean isValidBST(TreeNode root) {
if(root==null) return true;
if(!isValidBST(root.left)) return false;
if(root.val<=pre) return false;
pre = root.val;
return isValidBST(root.right);
}
}
代码(边界收缩):
java
class Solution {
boolean handle(TreeNode root,long lBorder,long rBorder){
if (root == null)
return true;
boolean a, b;
a = true;
b = true;
if (root.left != null)
if (root.left.val>lBorder&&root.left.val<root.val)
a = handle(root.left,lBorder,root.val);
else
return false;
if (root.right != null)
if (root.right.val>root.val&&root.right.val<rBorder)
b = handle(root.right,root.val,rBorder);
else
return false;
return a&b;
}
public boolean isValidBST(TreeNode root) {
return handle(root,Long.MIN_VALUE,Long.MAX_VALUE);
}
}
2843. 统计对称整数的数目
问题
给你两个正整数 low
和 high
。
对于一个由 2 * n
位数字组成的整数 x
,如果其前 n
位数字之和与后 n
位数字之和相等,则认为这个数字是一个对称整数。
返回在 [low, high]
范围内的 对称整数的数目 。
思路:
找特殊数,最简单的方法就是把所有可能用到的特殊数都记下来,然后枚举特殊数进行判断.当然范围较小的情况下遍历范围里的数其实也差不多
当然,也可以直接枚举每位判断
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
代码(哈希字典1):
java
class Solution {
public int countSymmetricIntegers(int low, int high) {
int[] hash = new int[1000];
int l = 0;
for(int i=1;i<10;i++){
hash[l++] = i+10*i;
}
for(int i=1;i<10;i++){
for(int j=0;j<10;j++){
for(int k=0;k<10&&k<=i+j;k++){
if(i+j-k>=10) continue;
hash[l++]=(i*1000+j*100+k*10+(i+j-k));
}
}
}
int ans = 0;
for(int i:hash){
if(i<low) continue;
if(i>high||i==0) break;
ans++;
}
return ans;
}
}
代码(哈希字典2):
java
class Solution {
public int countSymmetricIntegers(int low, int high) {
int[] hash = new int[10001];
for(int i=1;i<10;i++){
hash[i+10*i]++;
}
for(int i=1;i<10;i++){
for(int j=0;j<10;j++){
for(int k=0;k<10&&k<=i+j;k++){
if(i+j-k>=10) continue;
hash[(i*1000+j*100+k*10+(i+j-k))]++;
}
}
}
int ans = 0;
for(int i = low;i<=high;i++){
if(hash[i]==1) ans++;
}
return ans;
}
}
总结
今天主要是复习了二叉搜索树相关的概念.
往期打卡
*[617. 合并二叉树]: LeetCode
*[700. 二叉搜索树中的搜索]: LeetCode
*[98. 验证二叉搜索树]: LeetCode
*[654. 最大二叉树]: LeetCode
*[2843. 统计对称整数的数目]: LeetCode