二叉树
前序、中序、后序非递归遍历,只是打印节点的位置及条件不同。
前序
class Solution {
private:
vector<int> res;
public:
void pre(TreeNode* root)
{
if (!root) {
return;
}
res.push_back(root->val);
pre(root->left);
pre(root->right);
return;
}
vector<int> preorderTraversal(TreeNode* root) {
pre(root);
return res;
}
};
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> pre;
while (root || !pre.empty()) {
while(root) {
res.push_back(root->val);
pre.push(root);
root = root->left;
}
if (!pre.empty()) {
root = pre.top();
root = root->right;
pre.pop();
}
}
return res;
}
};
中序
class Solution {
private:
vector<int> res;
public:
void inorder(TreeNode *root) {
if (!root) {
return;
}
inorder(root->left);
res.push_back(root->val);
inorder(root->right);
}
vector<int> inorderTraversal(TreeNode* root) {
inorder(root);
return res;
}
};
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> in;
while (root || !in.empty()) {
while (root) {
in.push(root);
root = root->left;
}
if (!in.empty()) {
root = in.top();
in.pop();
res.push_back(root->val);
root = root->right;
}
}
return res;
}
};
后序
class Solution {
private:
vector<int> res;
public:
void post_order(TreeNode *root) {
if (!root) {
return;
}
post_order(root->left);
post_order(root->right);
res.push_back(root->val);
return;
}
vector<int> postorderTraversal(TreeNode* root) {
post_order(root);
return res;
}
};
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> post;
TreeNode *pre = NULL;
while (root || !post.empty()) {
while(root) {
post.push(root);
root = root->left;
}
if (!post.empty()) {
root = post.top();
if (!root->right || root->right == pre) {
res.push_back(root->val);
post.pop();
pre = root;
root = NULL;
} else {
root = root->right;
}
}
}
return res;
}
};
按层
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
queue<TreeNode*> q;
int n = 0;
if (!root) {
return res;
}
q.push(root);
while(!q.empty()) {
n = q.size();
vector<int> level;
while(n--) {
root = q.front();
q.pop();
level.push_back(root->val);
if (root->left) {
q.push(root->left);
}
if (root->right) {
q.push(root->right);
}
}
res.push_back(level);
}
return res;
}
};
Z字遍历
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
queue<TreeNode*> q;
int n = 0;
int flag = 0;
int len = 0;
if (!root) {
return res;
}
q.push(root);
while(!q.empty()) {
len = q.size();
vector<int> level(len);
for(int i = 0; i < len; i++) {
root = q.front();
q.pop();
int pos = flag ? len-1-i : i;
level[pos] = root->val;
if (root->left) {
q.push(root->left);
}
if (root->right) {
q.push(root->right);
}
}
res.push_back(level);
flag = flag == 0 ? 1 : 0;
}
return res;
}
};
反转二叉树
class Solution {
public:
void help(TreeNode* root) {
if (!root || (!root->right && !root->left)) {
return;
}
TreeNode *tmp = root->left;
root->left = root->right;
root->right = tmp;
help(root->left);
help(root->right);
}
TreeNode* invertTree(TreeNode* root) {
help(root);
}
};
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> s;
TreeNode *tmp = NULL;
TreeNode *cur = NULL;
if (!root) {
return root;
}
s.push(root);
while(!s.empty()) {
cur = s.top();
s.pop();
tmp = cur->right;
cur->right = cur->left;
cur->left = tmp;
if (cur->right) {
s.push(cur->right);
}
if (cur->left) {
s.push(cur->left);
}
}
return root;
}
};
路径和
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if (!root) {
return false;
}
if (!root->left && !root->right && root->val == targetSum) {
return true;
}
return hasPathSum(root->left, targetSum - root->val) || hasPathSum(root->right, targetSum - root->val);
}
};
打印路径
class Solution {
private:
vector<vector<int>> path;
vector<int> cur;
public:
void find_path(TreeNode* root, int targetSum) {
if (!root) {
return ;
}
cur.push_back(root->val);
if (!root->left && !root->right && root->val == targetSum) {
path.push_back(cur);
}
find_path(root->left, targetSum-root->val);
find_path(root->right, targetSum-root->val);
cur.pop_back();
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
find_path(root, targetSum);
return path;
}
};
最大深度
class Solution {
public:
int max_int(int a, int b) {
return a > b ? a : b;
}
int maxDepth(TreeNode* root) {
if (!root) {
return 0;
}
return max_int(maxDepth(root->left), maxDepth(root->right)) + 1;
}
};
class Solution {
public:
int maxDepth(TreeNode* root) {
queue<TreeNode*> q;
int deep = 0;
int n = 0;
if (!root) {
return res;
}
q.push(root);
while(!q.empty()) {
deep++;
n = q.size();
vector<int> level;
while(n--) {
root = q.front();
q.pop();
level.push_back(root->val);
if (root->left) {
q.push(root->left);
}
if (root->right) {
q.push(root->right);
}
}
}
return deep;
}
};
最小深度
递归的时候不能直接取左右孩子的最小值
因为有可能某个孩子不存在
如图,B的深度取决于左孩子D(深度1),而不是不存在的右孩子(深度0)
当某个孩子不存在时,取存在的深度
当都存在时,取最小值
class Solution {
public:
int min_int(int a, int b) {
return a < b ? a : b;
}
int max_int(int a, int b) {
return a > b ? a : b;
}
int minDepth(TreeNode* root) {
int left = 0;
int right = 0;
if (!root) {
return 0;
}
left = minDepth(root->left);
right = minDepth(root->right);
if (!left || !right) {
return max_int(left, right) + 1;
}
return min_int(left, right) + 1;
}
};
//按层遍历,第一个没有孩子的节点的深度就是最小深度
class Solution {
public:
int minDepth(TreeNode* root) {
queue<TreeNode*> q;
int deep = 0;
int flag = 0;
int n = 0;
if (!root) {
return 0;
}
q.push(root);
while(!q.empty()) {
deep++;
n = q.size();
while(n--) {
root = q.front();
q.pop();
if (!root->left && !root->right) {
flag = 1;
break;
}
if (root->left) {
q.push(root->left);
}
if (root->right) {
q.push(root->right);
}
}
if (flag) {
break;
}
}
return deep;
}
};
最大直径
对于一个节点,其直径就是左右子树的深度之和
依然求每个节点的左右子树深度,相加后记录,然后再遍历
class Solution {
public:
int max_int(int a, int b) {
return a > b ? a : b;
}
int depth(TreeNode* root, int *len) {
int left = 0;
int right = 0;
if (!root) {
return 0;
}
left = depth(root->left, len);
right = depth(root->right, len);
if (left + right > *len) {
*len = left + right;
}
return max_int(left, right) + 1;
}
int diameterOfBinaryTree(TreeNode* root) {
int len = 0;
depth(root, &len);
return len;
}
};
两棵树是否完全相同
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(!p && !q) {
return true;
}
if (!p || !q) {
return false;
}
if (p->val != q->val) {
return false;
}
return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
};
路径上节点组成的数字之和
num * 10有可能int溢出,所以使用long
class Solution {
private:
int sum = 0;
public:
void numbers(TreeNode *root, long int num) {
if (!root) {
return;
}
num = num * 10 + root->val;
if (!root->left && !root->right) {
sum += num;
return;
}
numbers(root->left, num);
numbers(root->right,num);
return;
}
int sumNumbers(TreeNode* root) {
long int num = 0;
if (!root) {
return 0;
}
numbers(root, num);
return sum;
}
};