题目1:617.合并二叉树
解法一:递归法
将root2合并到root1上
如果root1的某个节点为空,则合并后的结果就是root2的节点,root2的节点为空同理;
如果两棵树的某个对应节点不为空则数值相加,然后递归左右子树。
当然也可以重新定义一棵树在上面进行构造。
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if (root1 == NULL) return root2; //root1为空,合并后的二叉树为root2
if (root2 == NULL) return root1;
root1->val += root2->val; //在root1的结构上添加root2
root1->left = mergeTrees(root1->left, root2->left);
root1->right = mergeTrees(root1->right, root2->right);
return root1;
}
};
解法二:迭代法
DFS的代码也并不复杂,用一个队列放两棵树对应节点
如果对应节点都不为空则入队、如果某
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if (root1 == NULL) return root2;
if (root2 == NULL) return root1;
queue<TreeNode*> que;
que.push(root1);
que.push(root2);
while (!que.empty()) {
TreeNode* node1 = que.front(); que.pop();
TreeNode* node2 = que.front(); que.pop();
node1->val += node2->val;
if (node1->left != NULL && node2->left != NULL) { //root1和root2的左子树都不为空,就放入队列中
que.push(node1->left);
que.push(node2->left);
}
if (node1->right != NULL && node2->right != NULL) { //root1和root2的右子树都不为空,就放入队列中
que.push(node1->right);
que.push(node2->right);
}
if (node1->left == NULL && node2->left != NULL) { //如果root1的左子树为空,就把root2的左子树挂到root1的左子树上
node1->left = node2->left;
}
if (node1->right == NULL && node2->right != NULL) { //如果root1的右子树为空,就把root2的右子树挂到root1的右子树上
node1->right = node2->right;
} //不用讨论root1的某个子树不为空、root2的对应子树为空的情况
}
return root1;
}
};
题目2:700.二叉搜索树中的搜索
二叉搜索树的左子树上所有节点都小于其根节点的值、右子树上所有节点都大于其根节点的值
解法一:递归法
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if (root == NULL) return NULL; //root为空则返回空节点
if (root->val == val) return root; //root等于目标值
if (root->val > val) return searchBST(root->left, val); //root->val>val,搜索左子树
if (root->val < val) return searchBST(root->right, val); //root->val<val,搜索右子树
//return searchBST(root->val > val ? root->left : root->right, val);
return NULL;
}
};
解法二:迭代法
可以利用二叉搜索树的性质,不需要额外的使用栈或队列
class Solution {
public:
TreeNode* 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;
}
};
题目3:98.验证二叉搜索树
解法一:递归法
根据搜索二叉树的性质,通过中序遍历,输出的节点数值是升序的
利用数组:
通过递归中序遍历将节点值放入数组中,然后检查数组是否升序
class Solution {
private:
vector<int> vec;
void traversal(TreeNode* root) {
if (root == NULL) return;
traversal(root->left);
vec.push_back(root->val); // 将二叉搜索树转换为有序数组
traversal(root->right);
}
public:
bool isValidBST(TreeNode* root) {
traversal(root);
for (int i = 1; i < vec.size(); i++) { //遍历数组
if (vec[i] <= vec[i - 1]) return false; //小于等于,二叉搜索树没有相同的元素
}
return true;
}
};
中序遍历:
class Solution {
public:
TreeNode* pre = NULL; //记录中序遍历的前一个节点
bool isValidBST(TreeNode* root) {
if (!root) return true;
if (!isValidBST(root->left)) return false; //判断当前节点的左子树是否满足二叉搜索树,如果不满足,直接返回false
if (pre && root->val <= pre->val) return false; //如果前一个节点不为空并且当前节点<=前一个节点,直接返回false
pre = root; //否则,将当前节点设置为pre
return isValidBST(root->right); //递归判断右子树
}
};
解法二:迭代法
用迭代法模拟中序遍历
class Solution {
public:
bool isValidBST(TreeNode* root) {
stack<TreeNode*> st;
TreeNode* cur = root;
TreeNode* pre = NULL; //记录前一个节点
while (cur != NULL || !st.empty()) {
if (cur != NULL) {
st.push(cur);
cur = cur->left;
}
else {
cur = st.top();
st.pop();
if (pre != NULL && cur->val <= pre->val)
return false;
pre = cur; //保存前一个访问的结点
cur = cur->right;
}
}
return true;
}
};