LeetCode654最大二叉树
思路:找到最大的座位父节点,左边看作左子树,右边看作右子树。递归实现。
关键点:数组的左闭右闭。
/**
* 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 constructMaximumBinaryTree(int[] nums) {
return construct(nums, 0, nums.length-1);
}
public TreeNode construct(int[] nums, int left, int right){
if(right - left < 0){
return null;
}
int max = 0;
int index = left;
for(int i=left;i<=right;i++){
if(nums[i]>max){
max = nums[i];
index = i;
}
}
TreeNode root = new TreeNode(max);
root.left = construct(nums, left, index-1);
root.right = construct(nums, index+1, right);
return root;
}
}
和中序结合前序/后序的那两题很像
/**
* 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 {
private:
TreeNode* traversal(vector<int>& nums){
if(nums.size() == 0) return NULL;
int index = 0;
int temp = 0;
for(int i=0;i<nums.size();i++){
if(nums[i] > temp){
temp = nums[i];
index = i;
}
}
int nodevalue = nums[index];
TreeNode* node = new TreeNode(nodevalue);
vector<int> left(nums.begin(), nums.begin()+index);
vector<int> right(nums.begin()+index+1, nums.end());
node->left = traversal(left);
node->right = traversal(right);
return node;
}
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
if(nums.size() == 0) return NULL;
return traversal(nums);
}
};
LeetCode617合并二叉树
关键点:不用考虑数值和null相加的情况。因为在其中一个为null时,直接返回另一个子树。不用考虑后面了。
/**
* 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 mergeTrees(TreeNode root1, TreeNode root2) {
// 从根节点开始,前序遍历
if(root1 == null){
return root2;
}
if(root2 == null){
return root1;
}
root1.val += root2.val; // 不需要再新建一个root了 直接覆盖到root1即可。
root1.left = mergeTrees(root1.left, root2.left);
root1.right = mergeTrees(root1.right, root2.right);
return root1;
}
}
/**
* 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:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
// 最巧妙地地方就是当root1 为NULL 直接返回root2的值;
// 如果root2为NULL 直接返回root1的值
if(root1 == NULL) return root2;
if(root2 == NULL) return root1;
int sum = root1->val + root2->val;
TreeNode* root = new TreeNode(sum);
root->left = mergeTrees(root1->left, root2->left);
root->right = mergeTrees(root1->right, root2->right);
return root;
}
};
LeetCode700二叉搜索树中的搜索
二叉搜索树(Binary Search Tree,BST)是一种特殊的二叉树,它具有以下性质:
- 对于任意一个节点,它的左子树中的所有节点的值都小于它的值,而它的右子树中的所有节点的值都大于它的值。
- 左子树和右子树也都是二叉搜索树。
基于这个性质,我们可以利用二叉搜索树进行快速的查找、插入和删除等操作,时间复杂度通常为 O(log n)。
思路:
- 对于普通二叉树:
- 先找父节点,如果父节点是,就返回;
- 在找左节点,如果左节点返回的是null,就没有,返回不为null,就直接返回
- 最后找右节点。
- 对于二叉搜索树:
- 可判断root.val和val的大小关系,转到左子树或右子树。
/**
* 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 searchBST(TreeNode root, int val) {
// 在普通树中还是需要考虑遍历顺序:这里是前序
if(root == null || root.val == val){//如果到了空,或者root就是val的时候就返回
return root;
}
TreeNode left = searchBST(root.left, val);// 父节点不是就先看左子树
if(left != null){// 如果左子树的返回值不是null那就是有target。
return left;
}
return searchBST(root.right, val);// 左子树没有就在右子树找,找到就返回root,找不到就返回null
}
}
/**
* 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 searchBST(TreeNode root, int val) {
if(root == null || root.val == val){
return root;
}
if(root.val>val){
return searchBST(root.left, val);
}
else if(root.val<val){
return searchBST(root.right, val);
}
return null;
}
}
LeetCode98验证二叉搜索树
思路:按照中序遍历,将二叉树遍历到数组里。再检查数组是否递增。
/**
* 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 {
TreeNode max;
public boolean isValidBST(TreeNode root) {
// 中序遍历
if(root == null){ // 空数也为true,如果,
return true;
}
boolean left = isValidBST(root.left); //左,
if(left == false){ // 如果左边不符合则返回false
return false;
}
if(max != null && max.val >=root.val){ // max 用来标记
return false;
}
max = root;
return isValidBST(root.right);
}
}
/**
* 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:
long long max = LONG_MIN; // 设置为全局变量,不能在递归里面设置。要保持这个值是最新的
bool isValidBST(TreeNode* root) {
if(root==NULL) return true; // 空二叉树也是二叉搜索树
// 充分利用二叉搜索树的性质:中序遍历
bool left = isValidBST(root->left); // 左:left已经是下一步的返回值为 bool值
if(max< root->val) max = root->val; // 中:比较当前的节点值,与上一步的max的值的大小,如果保持递增就是对的。这样就避免了之前代码的bug [5,4,6,null,null,3,7]
else return false; // 遇到异常返回错误
bool right = isValidBST(root->right); // 右
return left && right; // 判断左子树和右子树的交集
}
};
双指针优化,更易理解。
思路:分别比较root和root.left;root和root.right。利用两个指针记录root的左右两侧,在递归。当出现左中右不递增的时候返回false,否则一直遍历到null返回true。
/**
* 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 boolean isValidBST(TreeNode root) {
// 中序遍历+双指针优化
long max = Long.MAX_VALUE;
long min = Long.MIN_VALUE;
return validBSt(min, max, root);
}
public boolean validBSt(long left, long right, TreeNode root){
// 左<中<右
// 两个指针分别对应root的左右,
// 比较左子树时,观察root.val 和 root.left的大小
// 比较右子树时,观察root.val 和 root.right的大小
if(root == null){
return true;
}
if(left>=root.val || right<=root.val){ // 左>=中 或者中>=右则false。
return false;
}
boolean leftTree = validBSt(left, root.val, root.left);
boolean rightTree = validBSt(root.val, right, root.right);
return leftTree && rightTree;
}
}