617.合并二叉树
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2
if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1
// 修改了t1的数值和结构
t1->val += t2->val; // 中
t1->left = mergeTrees(t1->left, t2->left); // 左
t1->right = mergeTrees(t1->right, t2->right); // 右
return t1;
}
如上的方法修改了t1的结构,当然也可以不修改t1和t2的结构,重新定义一个树。
不修改输入树的结构,前序遍历,代码如下:
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
if (t1 == NULL) return t2;
if (t2 == NULL) return t1;
// 重新定义新的节点,不修改原有两个树的结构
TreeNode* root = new TreeNode(0);
root->val = t1->val + t2->val;
root->left = mergeTrees(t1->left, t2->left);
root->right = mergeTrees(t1->right, t2->right);
return root;
}
700.二叉搜索树中的搜索
TreeNode* searchBST(TreeNode* root, int val) {
if(root==nullptr||root->val==val) return root;
TreeNode* result=nullptr;
if(root->val>val) result=searchBST(root->left,val);
if(root->val<val) result=searchBST(root->right,val);
return result;
}
迭代法:
reeNode* searchBST(TreeNode* root, int val) {
while (root != NULL) {
if (root->val > val) root = root->left;
else if (root->val < val) root = root->right;
else return root;
}
return NULL;
}
98.验证二叉搜索树
vector<int> vec;
void traversal(TreeNode* root){
if(root == NULL) return;
traversal(root->left);
vec.push_back(root->val);// 将二叉搜索树转换为有序数组
traversal(root->right);
}
bool isValidBST(TreeNode* root) {
vec.clear();
traversal(root);
for(int i = 1; i < vec.size(); i++){
// 注意要小于等于,搜索树里不能有相同元素
if(vec[i] <= vec[i-1]) return false;
}
return true;
}
要定义一个longlong的全局变量,用来比较遍历的节点是否有序,因为后台测试数据中有int最小值,所以定义为longlong的类型,初始化为longlong最小值。
long long maxVal = LONG_MIN;// 因为后台测试数据中有int最小值
bool isValidBST(TreeNode* root) {
if(root == NULL) return true;
bool left = isValidBST(root->left);
// 中序遍历,验证遍历的元素是不是从小到大
if (maxVal < root->val) maxVal = root->val;
else return false;
bool right = isValidBST(root->right);
return left && right;
}
以上代码是因为后台数据有int最小值测试用例,所以都把maxVal改成了longlong最小值。
如果测试数据中有 longlong的最小值,怎么办?
不可能在初始化一个更小的值了吧。 建议避免 初始化最小值,如下方法取到最左面节点的数值来比较。
TreeNode* pre = NULL; // 用来记录前一个节点
bool isValidBST(TreeNode* root) {
if(root == NULL) return true;
bool left = isValidBST(root->left);
// 中序遍历,验证遍历的元素是不是从小到大
if (pre!=NULL && pre->val >= root->val)
return false;
pre=root;// 记录前一个节点
bool right = isValidBST(root->right);
return left && right;
}
530.二叉搜索树的最小绝对差
vector<int> vec;
void traversal(TreeNode* root) {
if (root == NULL) return;
traversal(root->left);
vec.push_back(root->val); // 将二叉搜索树转换为有序数组
traversal(root->right);
}
int getMinimumDifference(TreeNode* root) {
vec.clear();
traversal(root);
if (vec.size() < 2) return 0;
int result = INT_MAX;
for (int i = 1; i < vec.size(); i++) { // 统计有序数组的最小差值
result = min(result, vec[i] - vec[i-1]);
}
return result;
}
双指针
TreeNode* pre = NULL; // 用来记录前一个节点
int result = INT_MAX;
void traversal(TreeNode* cur){
if(cur == NULL) return;
traversal(cur->left); // 左
if(pre != NULL) result=min(result,cur->val - pre->val);// 中
pre = cur;// 记录前一个
traversal(cur->right);// 右
}
int getMinimumDifference(TreeNode* root) {
traversal(root);
return result;
}
501.二叉搜索树中的众数
class Solution {
public:
int maxCount=0;// 最大频率
int count=0;// 统计频率
TreeNode* pre=NULL;
vector<int> result;
void searchBST(TreeNode* cur) {
if(cur==NULL) return;
searchBST(cur->left); // 左
//中
if(pre==NULL) // 第一个节点
count=1;
else if(pre->val==cur->val) // 与前一个节点数值相同
count++;
else // 与前一个节点数值不同
count=1;
pre=cur;// 更新上一个节点
if(count==maxCount) result.push_back(cur->val);// 如果和最大值相同,放进result中
if(count>maxCount){// 如果计数大于最大值频率
maxCount=count;// 如果计数大于最大值频率
result.clear();// 很关键的一步,不要忘记清空result,之前result里的元素都失效了
result.push_back(cur->val);
}
searchBST(cur->right); // 右
return ;
}
vector<int> findMode(TreeNode* root) {
count = 0;
maxCount = 0;
pre = NULL; // 记录前一个节点
result.clear();
searchBST(root);
return result;
}
};
236. 二叉树的最近公共祖先
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == q || root ==p || root ==NULL) return root;
TreeNode* left = lowestCommonAncestor(root->left,p,q);
TreeNode* right=lowestCommonAncestor(root->right,p,q);
if(left!=NULL && right!=NULL) return root;
else if(left == NULL && right != NULL) return right;
else if(left != NULL && right == NULL) return left;
else{// (left == NULL && right == NULL)
return NULL;
}
}