LeetCode题目:
- 654. 最大二叉树
- 617. 合并二叉树
- 700. 二叉搜索树中的搜索
- 98. 验证二叉搜索树
- 2843. 统计对称整数的数目
其他:
今日总结
往期打卡
654. 最大二叉树
跳转: 654. 最大二叉树
学习: 代码随想录公开讲解
问题:
给定一个不重复的整数数组 nums
。 最大二叉树 可以用下面的算法从 nums
递归地构建:
- 创建一个根节点,其值为
nums
中的最大值。 - 递归地在最大值 左边 的 子数组前缀上 构建左子树。
- 递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums
构建的 *最大二叉树* 。
思路:
这道题要求构造二叉树,使用前序遍历先构造自身再构造子树比较符合直觉,当然,先构造子节点再构造父节点后序遍历也是没有问题的,不过需要先存储子节点再构造父节点,比较麻烦.当然,用中序遍历也是,只需要先处理到左根,再创建节点,再绑定右子树即可.所以说前中后序只是创建节点的位置不同.
但这题用层序遍历就不是很合适,因为数组不是很好划分,要存储全部路径的边界状态.
因为需要获取两个子节点再操作本节点,所以使用迭代法比较麻烦.
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
代码(前序递归实现):
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. 合并二叉树
跳转: 617. 合并二叉树
学习: 代码随想录公开讲解
问题:
给你两棵二叉树: root1
和 root2
。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。
思路:
两棵树一起遍历,如果都不为null就合并,一方为null就返回另一方.
这里直接前序遍历
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( l o g n ) O(logn) O(logn)
代码:
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. 二叉搜索树中的搜索
跳转: 700. 二叉搜索树中的搜索
学习: 代码随想录公开讲解
问题:
给定二叉搜索树(BST)的根节点 root
和一个整数值 val
。
你需要在 BST 中找到节点值等于 val
的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null
。
思路:
这里直接利用二叉搜索树的性质选择递归方向即可
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( l o g n ) O(logn) O(logn)
代码:
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. 验证二叉搜索树
跳转: 98. 验证二叉搜索树
学习: 代码随想录公开讲解
问题:
给你一个二叉树的根节点 root
,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
思路:
右子树中所有节点都大于当前节点,左子树中所有节点都小于当前节点,基于此,可以使用边界收缩法,判断子节点是否在边界内
当然,二叉搜索树有一个很重要的性质,那就是中序遍历下单调递增.所以如果能想到这条性质可以降低编码复杂度,并提升代码效率.
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
代码(中序遍历):
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);}
}
代码(边界收缩):
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);elsereturn false;if (root.right != null)if (root.right.val>root.val&&root.right.val<rBorder)b = handle(root.right,root.val,rBorder);elsereturn false;return a&b;}public boolean isValidBST(TreeNode root) {return handle(root,Long.MIN_VALUE,Long.MAX_VALUE);}
}
2843. 统计对称整数的数目
跳转: 2843. 统计对称整数的数目
问题
给你两个正整数 low
和 high
。
对于一个由 2 * n
位数字组成的整数 x
,如果其前 n
位数字之和与后 n
位数字之和相等,则认为这个数字是一个对称整数。
返回在 [low, high]
范围内的 对称整数的数目 。
思路:
找特殊数,最简单的方法就是把所有可能用到的特殊数都记下来,然后枚举特殊数进行判断.当然范围较小的情况下遍历范围里的数其实也差不多
当然,也可以直接枚举每位判断
复杂度:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
代码(哈希字典1):
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):
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;}
}
总结
今天主要是复习了二叉搜索树相关的概念.
往期打卡
代码随想录算法训练营第十四天
代码随想录算法训练营第十三天
代码随想录算法训练营第十二天
代码随想录算法训练营第十一天
代码随想录算法训练营周末二
代码随想录算法训练营第十天
代码随想录算法训练营第九天
代码随想录算法训练营第八天
代码随想录算法训练营第七天
代码随想录算法训练营第六天
代码随想录算法训练营第五天
代码随想录算法训练营周末一
代码随想录算法训练营第四天
代码随想录算法训练营第三天
代码随想录算法训练营第二天
代码随想录算法训练营第一天