226. 翻转二叉树
法一:三种递归方法
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root){
invertTree(root->left);
invertTree(root->right);
swap(root->left,root->right);
// swap(root->left,root->right);
// invertTree(root->left);
// invertTree(root->right);
// invertTree(root->left);
// swap(root->left,root->right);
// invertTree(root->left);
}
return root;
}
};
法二:前序两次非递归
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> stack;
TreeNode* p=root;
while(p || !stack.empty()){
if(p){
swap(p->left, p->right);
stack.push(p);
p=p->left;
}else{
p=stack.top();
stack.pop();
p=p->right;
}
}
return root;
}
};
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> stack;
if(root)
stack.push(root);
while(!stack.empty()){
TreeNode* p=stack.top();
stack.pop();
swap(p->left,p->right);
if(p->right)
stack.push(p->right);
if(p->left)
stack.push(p->left);
}
return root;
}
};
法三:层次遍历
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
queue<TreeNode*> que;
if(root)
que.push(root);
while(!que.empty()){
TreeNode* p=que.front();
que.pop();
swap(p->left,p->right);
if(p->left)
que.push(p->left);
if(p->right)
que.push(p->right);
}
return root;
}
};
法一:递归
class Solution {
public:
bool isReverse(TreeNode* left,TreeNode* right){//判读根节点左右子树是否可以反转
if(left==NULL && right==NULL)
return true;
else if(left==NULL || right==NULL || left->val != right->val)
return false;
bool out = isReverse(left->left,right->right);
bool in = isReverse(left->right,right->left);
return out&∈
}
bool isSymmetric(TreeNode* root) {
if(root==NULL)
return true;
return isReverse(root->left,root->right);
}
};
法二:队列实现迭代法(也可以用栈实现,直接把queue换成stack即可)
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(root==NULL)
return true;
queue<TreeNode*> que;
que.push(root->left);
que.push(root->right);
while(!que.empty()){
TreeNode* left=que.front();que.pop();
TreeNode* right=que.front();que.pop();
if(!left && !right){
continue;
}else if(!left || !right || left->val!=right->val)
return false;
que.push(left->left);
que.push(right->right);
que.push(left->right);
que.push(right->left);
}
return true;
}
};
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(!p && !q)
return true;
else if(!p || !q || p->val!=q->val)
return false;
return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}
bool dfs(TreeNode* root,TreeNode* subRoot){
if(!root)
return false;
return isSameTree(root,subRoot) || dfs(root->left,subRoot) || dfs(root->right,subRoot);
}
bool isSubtree(TreeNode* root, TreeNode* subRoot) {
return dfs(root,subRoot);
}
};
104. 二叉树的最大深度
法一:递归
class Solution {
public:
int maxDepth(TreeNode* root) {
if(!root)
return 0;
return 1 + max(maxDepth(root->left),maxDepth(root->right));
}
};
法二:层次遍历
class Solution {
public:
int maxDepth(TreeNode* root) {
int depth=0;
queue<TreeNode*> que;
if(root)
que.push(root);
while(!que.empty()){
int size=que.size();
while(size--){
root=que.front();
que.pop();
if(root->left)
que.push(root->left);
if(root->right)
que.push(root->right);
}
depth++;
}
return depth;
}
};
法一:递归
class Solution {
public:
int minDepth(TreeNode* root) {
if (!root) return 0;
if (!root->left) return minDepth(root->right) + 1;
if (!root->right) return minDepth(root->left) + 1;
return min(minDepth(root->left), minDepth(root->right)) + 1;
}
};
法二:层次遍历
class Solution {
public:
int minDepth(TreeNode* root) {
int depth=0;
queue<TreeNode*> que;
if(root)
que.push(root);
while(!que.empty()){
int size=que.size();
depth++;
while(size--){
root=que.front();
que.pop();
if(root && !root->left && !root->right)
return depth;
if(root->left)
que.push(root->left);
if(root->right)
que.push(root->right);
}
}
return depth;
}
};
除了普通递归和层次遍历,这个是利用满二叉树的特性进行递归
class Solution {
public:
int countNodes(TreeNode* root) {
if (root == nullptr) return 0;
TreeNode* left = root->left;
TreeNode* right = root->right;
int leftDepth = 0, rightDepth = 0; // 这里初始为0是有目的的,为了下面求指数方便
while (left) { // 求左子树深度
left = left->left;
leftDepth++;
}
while (right) { // 求右子树深度
right = right->right;
rightDepth++;
}
if (leftDepth == rightDepth) {
return (2 << leftDepth) - 1; // 注意(2<<1) 相当于2^2,所以leftDepth初始为0
}
return countNodes(root->left) + countNodes(root->right) + 1;
}
};
法一:自底向上的递归
class Solution {
public:
int getHeight(TreeNode* node){
if(node==NULL)
return 0;
if(getHeight(node->left)==-1 || getHeight(node->right)==-1)
return -1;
int leftHeight = getHeight(node->left);
int rightHeight = getHeight(node->right);
return abs(leftHeight-rightHeight)>1 ? -1 : 1+max(leftHeight,rightHeight);
}
bool isBalanced(TreeNode* root) {
return getHeight(root)==-1 ? false :true;
}
};
法二:自顶向下的递归
class Solution {
public:
int height(TreeNode* root) {
if (root == NULL) {
return 0;
} else {
return max(height(root->left), height(root->right)) + 1;
}
}
bool isBalanced(TreeNode* root) {
if (root == NULL) {
return true;
} else {
return abs(height(root->left) - height(root->right)) <= 1 && isBalanced(root->left) && isBalanced(root->right);
}
}
};
法三:迭代
class Solution {
private:
int getDepth(TreeNode* cur) {
stack<TreeNode*> st;
if (cur != NULL) st.push(cur);
int depth = 0; // 记录深度
int result = 0;
while (!st.empty()) {
TreeNode* node = st.top();
if (node != NULL) {
st.pop();
st.push(node); // 中
st.push(NULL);
depth++;
if (node->right) st.push(node->right); // 右
if (node->left) st.push(node->left); // 左
} else {
st.pop();
node = st.top();
st.pop();
depth--;
}
result = result > depth ? result : depth;
}
return result;
}
public:
bool isBalanced(TreeNode* root) {
stack<TreeNode*> st;
if (root == NULL) return true;
st.push(root);
while (!st.empty()) {
TreeNode* node = st.top(); // 中
st.pop();
if (abs(getDepth(node->left) - getDepth(node->right)) > 1) {
return false;
}
if (node->right) st.push(node->right); // 右(空节点不入栈)
if (node->left) st.push(node->left); // 左(空节点不入栈)
}
return true;
}
};
回溯
class Solution {
private:
void traversal(TreeNode* cur, vector<int>& path, vector<string>& result) {
path.push_back(cur->val); // 中,中为什么写在这里,因为最后一个节点也要加入到path中
// 这才到了叶子节点
if (cur->left == NULL && cur->right == NULL) {
string sPath;
for (int i = 0; i < path.size() - 1; i++) {
sPath += to_string(path[i]);
sPath += "->";
}
sPath += to_string(path[path.size() - 1]);
result.push_back(sPath);
return;
}
if (cur->left) { // 左
traversal(cur->left, path, result);
path.pop_back(); // 回溯
}
if (cur->right) { // 右
traversal(cur->right, path, result);
path.pop_back(); // 回溯
}
}
public:
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
vector<int> path;
if (root == NULL) return result;
traversal(root, path, result);
return result;
}
};
精简版
class Solution {
private:
void traversal(TreeNode* cur, string path, vector<string>& result) {
path += to_string(cur->val); // 中
if (cur->left == NULL && cur->right == NULL) {
result.push_back(path);
return;
}
if (cur->left) traversal(cur->left, path + "->", result); // 左
if (cur->right) traversal(cur->right, path + "->", result); // 右
}
public:
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
string path;
if (root == NULL) return result;
traversal(root, path, result);
return result;
}
};
迭代
class Solution {
public:
vector<string> binaryTreePaths(TreeNode* root) {
stack<TreeNode*> treeSt;// 保存树的遍历节点
stack<string> pathSt; // 保存遍历路径的节点
vector<string> result; // 保存最终路径集合
if (root == NULL) return result;
treeSt.push(root);
pathSt.push(to_string(root->val));
while (!treeSt.empty()) {
TreeNode* node = treeSt.top();
treeSt.pop(); // 取出节点 中
string path = pathSt.top();
pathSt.pop(); // 取出该节点对应的路径
if (node->left == NULL && node->right == NULL) { // 遇到叶子节点
result.push_back(path);
}
if (node->right) { // 右
treeSt.push(node->right);
pathSt.push(path + "->" + to_string(node->right->val));
}
if (node->left) { // 左
treeSt.push(node->left);
pathSt.push(path + "->" + to_string(node->left->val));
}
}
return result;
}
};
法一:递归
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if (root == NULL) return 0;
int leftValue = 0;
if (root->left != NULL && root->left->left == NULL && root->left->right == NULL) {
leftValue = root->left->val;
}
return leftValue + sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);
}
};
法二:递归带参
class Solution {
public:
int result;
void dfs(TreeNode* root, bool is_left) {
if(!root) return;
dfs(root->left, true);
dfs(root->right, false);
if(!root->left && !root->right && is_left) {
result += root->val;
}
}
int sumOfLeftLeaves(TreeNode* root) {
result = 0;
dfs(root, false);
return result;
}
};
法三:迭代
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
stack<TreeNode*> stack;
if(root)
stack.push(root);
int sum = 0;
while(!stack.empty()){
root = stack.top();
stack.pop();
if(root->left && !root->left->left && !root->left->right){
sum += root->left->val;
}
if(root->right)
stack.push(root->right);
if(root->left)
stack.push(root->left);
}
return sum;
}
};
513. 找树左下角的值
法一:层序遍历
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> que;
if(root)
que.push(root);
TreeNode* p = root;
while(!que.empty()){
int size = que.size();
p = que.front();
while(size--){
root = que.front();
que.pop();
if(root->left)
que.push(root->left);
if(root->right)
que.push(root->right);
}
}
return p->val;
}
};
法二:递归
class Solution {
public:
int maxDepth = INT_MIN;
int result;
void traversal(TreeNode* root, int depth) {
if (root->left == NULL && root->right == NULL) {
if (depth > maxDepth) {
maxDepth = depth;
result = root->val;
}
return;
}
if (root->left) {
traversal(root->left, depth + 1); // 隐藏着回溯
}
if (root->right) {
traversal(root->right, depth + 1); // 隐藏着回溯
}
return;
}
int findBottomLeftValue(TreeNode* root) {
traversal(root,0);
return result;
}
};
法一:改257二叉树所有路径
class Solution {
public:
void traversal(TreeNode* cur, int sum, set<int>& result) {
sum += cur->val; // 中
if (cur->left == NULL && cur->right == NULL) {
result.insert(sum);
return;
}
if (cur->left) traversal(cur->left, sum, result); // 左
if (cur->right) traversal(cur->right, sum, result); // 右
}
bool hasPathSum(TreeNode* root, int targetSum) {
set<int> result;
int sum = 0;
if (root == NULL)
return false;
traversal(root, sum, result);
return result.find(targetSum)!=result.end();
}
};
法二:
class Solution {
private:
bool traversal(TreeNode* cur, int count) {
if (!cur->left && !cur->right && count == 0) return true; // 遇到叶子节点,并且计数为0
if (!cur->left && !cur->right) return false; // 遇到叶子节点直接返回
if (cur->left) { // 左
count -= cur->left->val; // 递归,处理节点;
if (traversal(cur->left, count)) return true;
count += cur->left->val; // 回溯,撤销处理结果
}
if (cur->right) { // 右
count -= cur->right->val; // 递归,处理节点;
if (traversal(cur->right, count)) return true;
count += cur->right->val; // 回溯,撤销处理结果
}
return false;
}
public:
bool hasPathSum(TreeNode* root, int sum) {
if (root == NULL) return false;
return traversal(root, sum - root->val);
}
};
精简版:
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
if (!root) return false;
if (!root->left && !root->right && sum == root->val) {
return true;
}
return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val);
}
};
class Solution {
public:
vector<vector<int>> result;
void traversal(TreeNode* node,int count,vector<int> vec){
if(!node->left && !node->right && count==0){
result.push_back(vec);
}
if(node->left){
vec.push_back(node->left->val);
traversal(node->left,count - node->left->val,vec);
vec.pop_back();
}
if(node->right){
vec.push_back(node->right->val);
traversal(node->right,count - node->right->val,vec);
vec.pop_back();
}
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
if(!root)
return result;
vector<int> vec;
vec.push_back(root->val);
traversal(root,targetSum - root->val,vec);
return result;
}
};