二叉树
- 101 对称二叉树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
return _isSymmetric(root, root);
}
bool _isSymmetric(TreeNode* rootA, TreeNode* rootB){
if(rootA==nullptr and rootB==nullptr) return true;
if(rootA==nullptr || rootB==nullptr) return false;
if(rootA->val != rootB->val) return false;
return _isSymmetric(rootA->left, rootB->right) && _isSymmetric(rootA->right, rootB->left);
}
};
- 二叉树的后序遍历
用哈希集合存储访问过的点,并且以根节点、右节点、左节点的顺序入栈,当第二次访问到根节点或者当前节点为叶子节点,就把值存入结果之中。
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
if(root == nullptr) return res;
unordered_set<TreeNode*> hash;
stack<TreeNode*> st;
st.push(root);
while(!st.empty()){
TreeNode* tmp = st.top();
st.pop();
if(hash.count(tmp)){//已经访问过一次
res.push_back(tmp->val);
}
else if(tmp->left==nullptr and tmp->right==nullptr) res.push_back(tmp->val);
else{
st.push(tmp);
if(tmp->right) st.push(tmp->right);
if(tmp->left) st.push(tmp->left);
hash.insert(tmp);
}
}
return res;
}
};
- 二叉树的最近公共祖先
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == p or root == q or root == nullptr) return root;
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if(left and right) return root;
if(left and right==nullptr) return left;
if(left == nullptr and right) return right;
return nullptr;
}
};
二叉搜索树
并不是左节点小于根节点,根节点小于右节点,而是要整个左子树的元素都应该小于根节点,整个右子树的元素都应该大于根节点,这就意味这在递归的过程中有上界和下界。
- 98 验证二叉搜索树
class Solution {
public:
bool isValidBST(TreeNode* root) {
return _isvalid(root, nullptr, nullptr);
}
bool _isvalid(TreeNode* root, TreeNode* lower, TreeNode* upper){
if(root == nullptr) return true;
if(lower and lower->val >= root->val) return false;
if(upper and upper->val <= root->val) return false;
return _isvalid(root->left, lower, root) and _isvalid(root->right, root, upper);
}
};
- 173 二叉搜索树迭代器
直接的解法会想到中序遍历,用数组存储下就行。
class BSTIterator {
public:
BSTIterator(TreeNode* root) {
inorder(root);
}
/** @return the next smallest number */
int next() {
int tmp = q.front();
q.pop();
return tmp;
}
/** @return whether we have a next smallest number */
bool hasNext() {
return !q.empty();
}
void inorder(TreeNode* root){
if(root == nullptr) return;
if(root->left) inorder(root->left);
q.push(root->val);
if(root->right) inorder(root->right);
return;
}
private:
queue<int> q;
};
但是上述算法的前提是得遍历一下树,时间复杂度和空间复杂度都随节点的个数增加,而提高效率的另一种方法就是可控制的递归,利用栈来模拟。
class BSTIterator {
public:
BSTIterator(TreeNode* root) {
step(root);
}
/** @return the next smallest number */
int next() {
int res;
if(!q.empty()){
TreeNode* tmp = q.top();
q.pop();
res = tmp->val;
step(tmp->right);
}
return res;
}
/** @return whether we have a next smallest number */
bool hasNext() {
return !q.empty();
}
void step(TreeNode* root){
while(root){
q.push(root);
root = root->left;
}
}
private:
stack<TreeNode*> q;
};
- 450 删除二叉搜索树中的节点
删除操作比较复杂,主要有三种情况,1)叶子节点 2)有一个子节点 3)有两个子节点,其实2)和3)可以归并一下,因为都是找前驱节点和后继节点。
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(root == nullptr) return nullptr; //空节点
if(root->val < key) root->right = deleteNode(root->right, key);
else if(root->val > key) root->left = deleteNode(root->left, key);
else{ //等于要删除的节点时有三种情况
TreeNode* temp;
if(root->left==nullptr and root->right==nullptr) root=nullptr; //叶子节点
else if(root->left){ //只有左孩子,找前继,左孩子的右孩子
temp = root->left;
while(temp->right){
temp = temp->right;
}
root->val = temp->val;
root->left = deleteNode(root->left, temp->val);
}
else{//只有右孩子,找后继,右孩子的左孩子
temp = root->right;
while(temp->left){
temp = temp->left;
}
root->val = temp->val;
root->right = deleteNode(root->right, temp->val);
}
}
return root;
}
};
二叉搜索树可以用于有序地存储数据或者需要同时执行搜索、插入、删除等多步操作
,