LeetCode 654 最大二叉树
题目链接:654
思路:先从数组中找到最大值,构造根节点,再分别递归左侧数组和右侧数组,构造左子树和右子树。
代码:
/**
* 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* constructMaximumBinaryTree(vector<int>& nums) {
if (nums.size() == 0) return NULL;
vector<int>::iterator max_it = max_element(nums.begin(), nums.end());
TreeNode* root = new TreeNode(*max_it);
vector<int> left(nums.begin(), max_it);
vector<int> right(max_it+1, nums.end());
root->left = constructMaximumBinaryTree(left);
root->right = constructMaximumBinaryTree(right);
return root;
}
};
LeetCode 617 合并二叉树
题目链接:617
递归 未参考版本
思路:采用前序遍历,先合并中间节点,再合并左右子树
代码:
/**
* 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) {
if (!root1 && !root2) return NULL;
TreeNode* root = new TreeNode();
if (!root1 && root2) {
root->val = root2->val;
root->left = mergeTrees(NULL, root2->left);
root->right = mergeTrees(NULL, root2->right);
}
else if (root1 && !root2) {
root->val = root1->val;
root->left = mergeTrees(root1->left, NULL);
root->right = mergeTrees(root1->right, NULL);
}
else {
root->val = root1->val + root2->val;
root->left = mergeTrees(root1->left, root2->left);
root->right = mergeTrees(root1->right, root2->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 {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if (!root1) return root2;
if (!root2) return root1;
root1->val = root1->val + root2->val;
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) {
if (!root1) return root2;
if (!root2) 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 = node1->val + node2->val;
if (node1->left && node2->left) {
que.push(node1->left);
que.push(node2->left);
}
if (node1->right && node2->right) {
que.push(node1->right);
que.push(node2->right);
}
if (!node1->left && node2->left) node1->left = node2->left;
if (!node1->right && node2->right) node1->right = node2->right;
}
return root1;
}
};
LeetCode 700 二叉搜索树中的搜索
题目链接:700
递归
思路:只需根据当前节点与目标的大小,选择向左或向右递归即可
代码:
/**
* 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* searchBST(TreeNode* root, int val) {
if (!root) return NULL;
TreeNode* result;
if (root->val == val) result = root;
if (root->val < val) result = searchBST(root->right, val);
if (root->val > val) result = searchBST(root->left, val);
return result;
}
};
迭代
/**
* 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* searchBST(TreeNode* root, int val) {
TreeNode* cur = root;
while (cur) {
if (cur->val == val) return cur;
if (cur->val > val) cur = cur->left;
else if (cur->val < val) cur = cur->right;
}
return NULL;
}
};
LeetCode 98 验证二叉搜索树
递归 未参考
思路:前序遍历,先判断左子树中的最大值是否小于当前节点,再递归左子树判断是否是二叉搜索;右子树同理。
代码:
/**
* 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:
bool isValidBST(TreeNode* root) {
if (!root->left && !root->right) return true;
bool valid_left = true, valid_right = true;
if (root->left) {
TreeNode* left = root->left;
int left_max;
while (left) {
left_max = left->val;
left = left->right;
}
valid_left = (left_max < root->val) && isValidBST(root->left);
}
if (root->right) {
TreeNode* right = root->right;
int right_min;
while (right) {
right_min = right->val;
right = right->left;
}
valid_right = (right_min > root->val) && isValidBST(root->right);
}
return valid_left && valid_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:
vector<int> vec;
void recurse(TreeNode* root) {
if (!root) return;
recurse(root->left);
vec.push_back(root->val);
recurse(root->right);
}
bool isValidBST(TreeNode* root) {
vec.clear();
recurse(root);
for (int i=1; i<vec.size(); ++i) {
if (vec[i-1] >= vec[i]) return false;
}
return true;
}
};
递归 简洁
思路:中序遍历时,保存前一个节点,每次判断当前节点是否大于前一个节点
代码:
/**
* 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* pre = NULL;
bool isValidBST(TreeNode* root) {
if (!root) return true;
bool left = isValidBST(root->left);
if (pre && pre->val >= root->val) return false;
else pre = root;
bool right = isValidBST(root->right);
return left && 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:
bool isValidBST(TreeNode* root) {
stack<TreeNode*> stk;
TreeNode* cur = NULL;
TreeNode* pre = NULL;
if (root) stk.push(root);
while (!stk.empty()) {
cur = stk.top();
stk.pop();
if (cur) {
if (cur->right) stk.push(cur->right);
stk.push(cur);
stk.push(NULL);
if (cur->left) stk.push(cur->left);
} else {
cur = stk.top();
stk.pop();
if (pre && cur->val <= pre->val) return false;
pre = cur;
}
}
return true;
}
};