654.最大二叉树
又是构造二叉树,昨天大家刚刚做完 中序后序确定二叉树,今天做这个 应该会容易一些, 先看视频,好好体会一下 为什么构造二叉树都是 前序遍历
题目链接/文章讲解:代码随想录
视频讲解:又是构造二叉树,又有很多坑!| LeetCode:654.最大二叉树_哔哩哔哩_bilibili
代码:
public TreeNode constructMaximumBinaryTree(int[] nums) { return conleft(nums,0,nums.length); } public TreeNode conleft(int[]nums,int l,int r){ if(r-l < 1){ return null; } if(r-l == 1){ return new TreeNode(nums[l]); } int maxValueIndex = l; int maxValue = nums[maxValueIndex]; for (int i = l+1; i < r; i++) { if (nums[i] > maxValue) { maxValue = nums[i]; maxValueIndex = i; } } TreeNode root = new TreeNode(maxValue); root.left = conleft(nums,l,maxValueIndex); root.right = conleft(nums,maxValueIndex+1,r); return root; }
别忘了最基本的找最大值:
int maxValueIndex = l; int maxValue = nums[maxValueIndex]; for (int i = l+1; i < r; i++) { if (nums[i] > maxValue) { maxValue = nums[i]; maxValueIndex = i; } }
617.合并二叉树
这次是一起操作两个二叉树了, 估计大家也没一起操作过两个二叉树,也不知道该如何一起操作,可以看视频先理解一下。 优先掌握递归。
题目链接/文章讲解:代码随想录
视频讲解:一起操作两个二叉树?有点懵!| LeetCode:617.合并二叉树_哔哩哔哩_bilibili
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) { if (root1 == null) return root2; if (root2 == null) return root1; root1.val += root2.val; root1.left = mergeTrees(root1.left,root2.left); root1.right = mergeTrees(root1.right,root2.right); return root1; }
700.二叉搜索树中的搜索
递归和迭代 都可以掌握以下,因为本题比较简单, 了解一下 二叉搜索树的特性
题目链接/文章讲解: 代码随想录
视频讲解:不愧是搜索树,这次搜索有方向了!| LeetCode:700.二叉搜索树中的搜索_哔哩哔哩_bilibili
TreeNode ans = null; public TreeNode searchBST(TreeNode root, int val) { searchans(root,val); return ans; } public void searchans(TreeNode root,int val){ if(root == null){ return; } if(root.val == val){ ans = root; }else if(root.val < val){ searchBST(root.right,val); }else{ searchBST(root.left,val); } }
98.验证二叉搜索树
遇到 搜索树,一定想着中序遍历,这样才能利用上特性。
但本题是有陷阱的,可以自己先做一做,然后在看题解,看看自己是不是掉陷阱里了。这样理解的更深刻。
题目链接/文章讲解:代码随想录
视频讲解:你对二叉搜索树了解的还不够! | LeetCode:98.验证二叉搜索树_哔哩哔哩_bilibili
写了一版就是掉进陷阱的
public boolean isValidBST(TreeNode root) { if(root == null){ return true; } return isValidBST(root.left) && isValidBST(root.right) && isL(root.left,root.val) && isR(root.right,root.val); } public boolean isL(TreeNode root,int val){ if(root == null){ return true; } if(root.val>=val){ return false; }else{ return true; } } public boolean isR(TreeNode root,int val){ if(root == null){ return true; } if(root.val<=val){ return false; }else{ return true; } }
正确递归版本:
// 递归 TreeNode max; public boolean isValidBST(TreeNode root) { if (root == null) { return true; } // 左 boolean left = isValidBST(root.left); if (!left) { return false; } // 中 if (max != null && root.val <= max.val) { return false; } max = root; // 右 boolean right = isValidBST(root.right); return right; }
class Solution { // 最小值初始化为中序序列的第一个节点值 Integer pre; public boolean isValidBST(TreeNode root) { // 结束条件:如果root为null,返回true。 // 因为空的二叉搜索树也是符合条件的 if (root == null) return true; // 中序遍历:左根右 // 递归左子树,获取结果 boolean left = isValidBST(root.left); // 如果当前节点的值大于等于中序序列中上一个值,证明不是二叉搜索树 // 如果pre为null,证明pre还没有初始化所以首先将pre初始化 if (pre != null && root.val <= pre){ return false; } // 如果当前节点小于中序序列上一个值,证明符合条件,更新pre为 // 当前值,继续判断下一个值, pre = root.val; // 递归右子树,获取结果 boolean right = isValidBST(root.right); // 左右子树都是二叉搜索树,则返回true,否则返回false return left && right; } } 关于初始值的优化:因为测试数据中有int类型的最小值,所以取long类型的最小值作为初始值。但是这样治标不治本,如果测试数据中存在long类型的最小值,不可能再初始化一个更小的值,所以建议取二叉树中序遍历序列的第一个值作为初始值。