BM35-BM38
BM35 判断是不是完全二叉树
***解题思路:***
- 法一:层序遍历(以无右子树的节点为标记)
- 法二:层序遍历(遇到空节点后,则队列中其余元素全为空)
#include <queue>
class Solution1 {
public:
bool isCompleteTree(TreeNode* root) {
if (root == nullptr || (!root->left && !root->right))return true;
bool mask = false;
queue<TreeNode*> qtn;
qtn.push(root);
while (!qtn.empty()) {
TreeNode* tmp = qtn.front();
qtn.pop();
if (tmp->right && !tmp->left)return false;
if (!mask) {
if (tmp->left) qtn.push(tmp->left);
if (!tmp->right)
mask = true;
else
qtn.push(tmp->right);
} else if (tmp->left || tmp->right)
return false;
}
return true;
}
};
class Solution {
public:
bool isCompleteTree(TreeNode* root) {
if (root == nullptr)return true;
TreeNode* star = root->left;
int level = 0, lcnt = 0;
queue<TreeNode*> qtn;
qtn.emplace(root);
while (!qtn.empty()) {
TreeNode* tmp = qtn.front();
qtn.pop();
if (tmp == nullptr)break;
qtn.push(tmp->left);
qtn.push(tmp->right);
}
while(!qtn.empty()){
TreeNode* tmp = qtn.front();
qtn.pop();
if (tmp != nullptr)return false;
}
return true;
}
};
BM36 判断是不是平衡二叉树
***解题思路:***
- 法一:递归(左右子树的高度差是否大于1)
class Solution {
public:
bool flag = true;
bool IsBalanced_Solution(TreeNode* pRoot) {
if (pRoot == nullptr)return true;
process(pRoot);
return flag;
}
int process(TreeNode* node) {
if (!flag || node == nullptr)return 0;
int llevel = process(node->left);
int rlevel = process(node->right);
if (abs(llevel - rlevel) > 1) flag = false;
return max(llevel, rlevel) + 1;
}
};
BM37 二叉搜索树的最近公共祖先
***解题思路:***
- 法一:递归(最大值小于根节点,到左侧找;最小值大于根节点,到右侧找)
- 法二:法二:哈希表记录各节点和其父节点,set记录根节点到某节点的路径,再利用另一节点向上寻找公共祖先
class Solution1 {
public:
int lowestCommonAncestor(TreeNode* root, int p, int q) {
if (root == nullptr)return -1;
if (p > q) {
p = p ^ q;
q = p ^ q;
p = p ^ q;
}
if (root->val == p || root->val == q || (root->val > p && root->val < q))
return root->val;
if (root->val > q)
return lowestCommonAncestor(root->left, p, q);
return lowestCommonAncestor(root->right, p, q);
}
};
BM38 在二叉树中找到两个节点的最近公共祖先
***解题思路:***
- 法一:递归(1、左空右不空 或 右空左不空。2、左右都不空)
- 法二:子父节点配对,找到根节点到其中一个节点的路径set1,然后从另一个节点向上追溯,直至其祖先位于set1为止。(unordered_map + unordered_set)
- 法三:找到根节点到其中一个节点的路径stack,然后以栈各元素为根节点找寻另一个节点。(unordered_set + stack)
class Solution {
public:
int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
TreeNode* node = Ancestor(root, o1, o2);
return node->val;
}
TreeNode* Ancestor(TreeNode* root, int o1, int o2) {
if (root == nullptr || root->val == o1 || root->val == o2)return root;
TreeNode* lnode = Ancestor(root->left, o1, o2);
TreeNode* rnode = Ancestor(root->right, o1, o2);
if (lnode != nullptr && rnode != nullptr)return root;
return lnode == nullptr ? rnode : lnode;
}
};
#include <fstream>
#include <functional>
#include <unordered_set>
class Solution2 {
public:
int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
unordered_map<TreeNode*, TreeNode*> ttmap;
ttmap.emplace(root, root);
pair<TreeNode*, TreeNode*> node12;
process(root, ttmap, node12, o1, o2);
unordered_set<TreeNode*> set1;
TreeNode* cur = node12.first;
while (cur != ttmap[cur]) {
set1.emplace(cur);
cur = ttmap[cur];
}
set1.emplace(root);
cur = node12.second;
while (set1.find(cur) == set1.end()) {
cur = ttmap[cur];
}
return cur->val;
}
void process(TreeNode* node,
unordered_map<TreeNode*, TreeNode*>& ttmap, pair<TreeNode*, TreeNode*>& node12,
int o1,
int o2) {
if (node == nullptr || (node12.first != nullptr &&
node12.second != nullptr))return;
if (node->val == o1 || node->val == o2) {
if (node12.first == nullptr)node12.first = node;
else node12.second = node;
}
if (node->left)ttmap.emplace(node->left, node);
if (node->right)ttmap.emplace(node->right, node);
process(node->left, ttmap, node12, o1, o2);
process(node->right, ttmap, node12, o1, o2);
}
};
class Solution3 {
public:
unordered_set<TreeNode*> checkset;
stack<TreeNode*> spath;
int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
process(root, o1, o2);
int vtmp = spath.top()->val;
int vsize = spath.size();
int o = spath.top()->val == o1 ? o2 : o1;
TreeNode* tmp;
while (!spath.empty()) {
tmp = spath.top();
spath.pop();
if (check(tmp, o))break;
checkset.emplace(tmp);
}
return tmp->val;
}
bool process(TreeNode* node, int o1, int o2) {
spath.emplace(node);
if (node->val == o1 || node->val == o2) {
return true;
} else if (node->left || node->right) {
if (node->left) {
if (process(node->left, o1, o2))return true;
spath.pop();
}
if (node->right) {
if (process(node->right, o1, o2))return true;
spath.pop();
}
}
return false;
}
bool check(TreeNode* node, int o) {
if (node == nullptr || checkset.find(node) != checkset.end())return false;
if (node->val == o || check(node->left, o) || check(node->right, o))return true;
return false;
}
};