树的定义
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x): val(x), left(NULL), right(NULL) {}
TreeNode(int x, TreeNode* left, TreeNode* right): val(x), left(left), right(right) {}
};
1.前序
https://leetcode-cn.com/problems/binary-tree-preorder-traversal/
非递归:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
if (root == NULL) {
return res;
}
stack<TreeNode*> st;
while(root || !st.empty()) {
if (root) {
st.push(root);
res.push_back(root->val);
root = root->left;
} else {
TreeNode* temp = st.top();
st.pop();
root = temp->right;
}
}
return res;
}
2.中序
https://leetcode-cn.com/problems/binary-tree-inorder-traversal/
非递归:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
if (root == NULL) {
return res;
}
stack<TreeNode*> q;
while(root || !q.empty()) {
if (root) {
q.push(root);
root = root->left;
} else {
TreeNode* temp = q.top();
q.pop();
res.push_back(temp->val);
root = temp->right;
}
}
return res;
}
3.后续
https://leetcode-cn.com/problems/binary-tree-postorder-traversal/
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
if (root == NULL) {
return res;
}
stack<TreeNode*> st;
while(root || !st.empty()) {
if (root) {
st.push(root);
//易错点:注意插入位置
res.insert(res.begin(), root->val);
root = root->right;
} else {
TreeNode* temp = st.top();
st.pop();
root = temp->left;
}
}
return res;
}
4.层次遍历
https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/
int maxDepth(TreeNode* root) {
if (root == NULL) {
return 0;
}
if (root->left == NULL && root->right == NULL) {
return 1;
}
queue<TreeNode*> q;
q.push(root);
int res = 0;
while(!q.empty()) {
//每层的个数
int len = q.size();
for (int i = 0; i < len; i++) {
TreeNode* temp = q.front();
if (temp->left) {
q.push(temp->left);
}
if (temp->right) {
q.push(temp->right);
}
q.pop();
}
res += 1;
}
return res;
}
5.生成树
前序+中序构建二叉树
https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (preorder.size() == 0) {
return NULL;
}
vector<int> left_preorder;
vector<int> left_inorder;
vector<int> right_preorder;
vector<int> right_inorder;
int temp = preorder[0];
TreeNode* root = new TreeNode(temp);
int idx = 0;
for (; idx < inorder.size(); idx++) {
if (inorder[idx] == temp) {
break;
} else {
left_inorder.push_back(inorder[idx]);
}
}
for (int i = 1; i < preorder.size(); i++) {
if (i < idx + 1) {
left_preorder.push_back(preorder[i]);
} else {
right_preorder.push_back(preorder[i]);
}
}
//易错点:将root过滤掉
idx += 1;
for (; idx < inorder.size(); idx++) {
right_inorder.push_back(inorder[idx]);
}
root->left = buildTree(left_preorder, left_inorder);
root->right = buildTree(right_preorder, right_inorder);
return root;
}
中序+后续构建二叉树
https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if (inorder.size() == 0) {
return NULL;
}
int temp = postorder[postorder.size() - 1];
TreeNode* root = new TreeNode(temp);
vector<int> left_inorder;
vector<int> left_postorder;
vector<int> right_inorder;
vector<int> right_postorder;
int idx = 0;
for (; idx < inorder.size(); idx++) {
if (inorder[idx] == temp) {
break;
} else {
left_inorder.push_back(inorder[idx]);
}
}
for (int i = 0; i < postorder.size() - 1; i++) {
if (i < idx) {
left_postorder.push_back(postorder[i]);
} else {
right_postorder.push_back(postorder[i]);
}
}
idx += 1;
for (; idx < inorder.size(); idx++) {
right_inorder.push_back(inorder[idx]);
}
root->left = buildTree(left_inorder, left_postorder);
root->right = buildTree(right_inorder, right_postorder);
return root;
}
6.root到某一节点和
https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/
void dfs(TreeNode* root, int target, vector<vector<int> >& res, vector<int> temp) {
if (root == NULL) {
return;
}
//保存结果
if (root->left == NULL && root->right == NULL && target == root->val) {
temp.push_back(root->val);
res.push_back(temp);
}
if (root->left) {
temp.push_back(root->val);
dfs(root->left, target - root->val, res, temp);
temp.pop_back();
}
if (root->right) {
temp.push_back(root->val);
dfs(root->right, target - root->val, res, temp);
temp.pop_back();
}
}
vector<vector<int> > pathSum(TreeNode* root, int target) {
vector<vector<int> > res;
vector<int> temp;
dfs(root, target, res, temp);
return res;
}
7.二叉树深度、平衡二叉树
https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/
递归:
int maxDepth(TreeNode* root) {
if (root == NULL) {
return 0;
}
if (root->left == NULL && root->right == NULL) {
return 1;
}
//保存左右树的高度
int leftvalue = maxDepth(root->left);
int rightvalue = maxDepth(root->right);
return max(leftvalue, rightvalue) + 1;
}
int main() {
TreeNode *root = new TreeNode(3);
TreeNode *left1 = new TreeNode(9);
root->left = left1;
TreeNode *right1 = new TreeNode(20);
root->right = right1;
TreeNode *left2 = new TreeNode(15);
right1->left = left2;
TreeNode *right2 = new TreeNode(7);
right1->right = right2;
int value = maxDepth(root);
cout << value << endl;
return 0;
}
非递归:
//层次遍历
int maxDepth(TreeNode* root) {
if (root == NULL) {
return 0;
}
if (root->left == NULL && root->right == NULL) {
return 1;
}
queue<TreeNode*> q;
q.push(root);
int res = 0;
while(!q.empty()) {
int len = q.size();
for (int i = 0; i < len; i++) {
TreeNode* temp = q.front();
if (temp->left) {
q.push(temp->left);
}
if (temp->right) {
q.push(temp->right);
}
q.pop();
}
res += 1;
}
return res;
}
后续:树的最小高度、平衡二叉树都是上序代码的演变
8.公共祖先
二叉搜索树公共祖先
https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == p || root == q) {
return root;
}
if ((root->val > p->val && root->val < q->val) ||
(root->val < p->val && root->val > q->val)) {
return root;
}
//易错点:递归二分,一定要加判断,否则会出错
if (root->val > q->val && root->val > q->val) {
return lowestCommonAncestor(root->left, p, q);
} else {
return lowestCommonAncestor(root->right, p, q);
}
return root;
}
二叉树公共祖先
https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/
void dfs(TreeNode* root, TreeNode* p, vector<TreeNode*>& temp1, vector<TreeNode*>& res) {
if (root == NULL) {
return;
}
temp1.push_back(root);
//错误点,一定要进行保存,否则会被回溯
if (root == p) {
res = temp1;
return;
}
if (root->left) {
dfs(root->left, p, temp1, res);
}
if (root->right) {
dfs(root->right, p, temp1, res);
}
temp1.pop_back();
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
vector<TreeNode*> temp1;
vector<TreeNode*> temp2;
vector<TreeNode*> res;
//temp1.push_back(root);
//temp2.push_back(root);
dfs(root, p, temp1, res);
temp1 = res;
res.clear();
dfs(root, q, temp2, res);
temp2 = res;
int i = 0;
while(i < temp1.size() && i < temp2.size()) {
if (temp1[i] == temp2[i]) {
i += 1;
} else {
break;
}
}
return temp1[i - 1];
}
非递归
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
stack<TreeNode*> t;
//map用来放父节点数据,用随便一个遍历方法即可得到所有的父节点
map<TreeNode*, TreeNode*> mp;
while(root || !t.empty()) {
if (root) {
t.push(root);
mp[root->left] = root;
root = root->left;
} else {
TreeNode* temp = t.top();
t.pop();
mp[temp->right] = temp;
root = temp->right;
}
}
//存放p、q节点路径
vector<TreeNode*> path_q, path_p;
path_p.push_back(p);
while(mp[p]) {
path_p.insert(path_p.begin(), mp[p]);
p = mp[p];
}
path_q.push_back(q);
while(mp[q]) {
path_q.insert(path_q.begin(), mp[q]);
q = mp[q];
}
int i = 0;
while(i < path_q.size() && i < path_p.size() && path_p[i] == path_q[i]) {
i += 1;
}
return path_q[i - 1];
}