力扣226—翻转二叉树
题意
解法1—深度优先遍历(前序遍历+递归)
我们可以前序遍历二叉树中的每个节点,然后翻转每个节点的左右节点,即可达到翻转整颗二叉树的效果。
class Solution
{
public:
void in_order(TreeNode* root)
{
if(root==nullptr)
return;
swap(root->left,root->right);
in_order(root->left);
in_order(root->right);
}
TreeNode* invertTree(TreeNode* root)
{
if(nullptr==root)
return root;
in_order(root);
return root;
}
};
解法2—非递归
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution
{
public:
void in_order(TreeNode* root)
{
if(root==nullptr)
return;
swap(root->left,root->right);
in_order(root->left);
in_order(root->right);
}
TreeNode* invertTree(TreeNode* root)
{
if(nullptr==root)
return root;
//前序遍历+递归
//in_order(root);
//利用栈
stack<TreeNode*> st;
st.push(root);
while(!st.empty())
{
TreeNode* node=st.top();
st.pop();
swap(node->left,node->right);
if(node->right)
st.push(node->right);
if(node->left)
st.push(node->left);
}
return root;
}
};
解法3—广度优先遍历(队列)
class Solution
{
public:
void in_order(TreeNode* root)
{
if(root==nullptr)
return;
swap(root->left,root->right);
in_order(root->left);
in_order(root->right);
}
TreeNode* invertTree(TreeNode* root)
{
if(nullptr==root)
return root;
//前序遍历+递归
//in_order(root);
//利用栈
/*
stack<TreeNode*> st;
st.push(root);
while(!st.empty())
{
TreeNode* node=st.top();
st.pop();
swap(node->left,node->right);
if(node->right)
st.push(node->right);
if(node->left)
st.push(node->left);
}
return root;
*/
//法3:广度优先遍历,队列
queue<TreeNode*> que;
que.push(root);
while(!que.empty())
{
int size=que.size();
for(int i=0;i<size;i++)
{
TreeNode* node=que.front();
que.pop();
swap(node->left,node->right);
if(node->left)
que.push(node->left);
if(node->right)
que.push(node->right);
}
}
return root;
}
};
力扣112—路径总和
题意
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
叶子节点: 是指没有子节点的节点。
解法1—深度优先遍历(前序遍历+递归)
class Solution
{
public:
bool in_order(TreeNode* root,int targetSum,int roadSum)
{
roadSum+=root->val; //路径和
//如果该节点是叶子节点,判断路径和是否等于目标值
if(root->left==nullptr&&root->right==nullptr)
{
bool exist = targetSum==roadSum;
return exist;
}
else
{
bool left_exist=false,right_exist=false;
//如果该节点有左孩子,就进入左孩子分支
if(root->left)
{
left_exist=in_order(root->left,targetSum,roadSum);
}
//如果左孩子分支满足路径和==目标值,直接返回true,没必要继续往下执行了
if(true==left_exist)
return true;
//如果该节点左孩子分支不满足,且有右孩子,就进入右孩子分支
if(root->right)
{
right_exist=in_order(root->right,targetSum,roadSum);
}
return right_exist;
}
}
bool hasPathSum(TreeNode* root, int targetSum)
{
if(nullptr==root)
return false;
return in_order(root,targetSum,0);
}
};
解法2—广度优先遍历
记录从根节点到当前节点的路径和,以防止重复计算。这样我们使用两个队列,分别存储将要遍历的节点,以及根节点到这些节点的路径和即可。
class Solution
{
public:
bool in_order(TreeNode* root,int targetSum,int roadSum)
{
roadSum+=root->val; //路径和
//如果该节点是叶子节点,判断路径和是否等于目标值
if(root->left==nullptr&&root->right==nullptr)
{
bool exist = targetSum==roadSum;
return exist;
}
else
{
bool left_exist=false,right_exist=false;
//如果该节点有左孩子,就进入左孩子分支
if(root->left)
{
left_exist=in_order(root->left,targetSum,roadSum);
}
//如果左孩子分支满足路径和==目标值,直接返回true,没必要继续往下执行了
if(true==left_exist)
return true;
//如果该节点左孩子分支不满足,且有右孩子,就进入右孩子分支
if(root->right)
{
right_exist=in_order(root->right,targetSum,roadSum);
}
return right_exist;
}
}
bool hasPathSum(TreeNode* root, int targetSum)
{
if(nullptr==root)
return false;
// return in_order(root,targetSum,0);
//法2:广度优先遍历
queue<TreeNode*> st1;
queue<int> st2;
st1.push(root);
st2.push(root->val);
while(!st1.empty())
{
TreeNode* node=st1.front();
int tmp=st2.front(); //根节点到当前节点(node)的值
st1.pop();
st2.pop();
if(node->left==nullptr&&node->right==nullptr)
{
if(tmp==targetSum)
return true;
continue;
}
if(node->left)
{
st1.push(node->left);
st2.push(tmp+node->left->val); //将根节点到当前节点的和加上左孩子的和送入st2
}
if(node->right)
{
st1.push(node->right);
st2.push(tmp+node->right->val); //将根节点到当前节点的和加上右孩子的和送入st2
}
}
return false;
}
};
解法3—利用栈,非递归
class Solution
{
public:
bool in_order(TreeNode* root,int targetSum,int roadSum)
{
roadSum+=root->val; //路径和
//如果该节点是叶子节点,判断路径和是否等于目标值
if(root->left==nullptr&&root->right==nullptr)
{
bool exist = targetSum==roadSum;
return exist;
}
else
{
bool left_exist=false,right_exist=false;
//如果该节点有左孩子,就进入左孩子分支
if(root->left)
{
left_exist=in_order(root->left,targetSum,roadSum);
}
//如果左孩子分支满足路径和==目标值,直接返回true,没必要继续往下执行了
if(true==left_exist)
return true;
//如果该节点左孩子分支不满足,且有右孩子,就进入右孩子分支
if(root->right)
{
right_exist=in_order(root->right,targetSum,roadSum);
}
return right_exist;
}
}
bool hasPathSum(TreeNode* root, int targetSum)
{
if(nullptr==root)
return false;
// return in_order(root,targetSum,0);
//法2:广度优先遍历
/*
queue<TreeNode*> st1;
queue<int> st2;
st1.push(root);
st2.push(root->val);
while(!st1.empty())
{
TreeNode* node=st1.front();
int tmp=st2.front(); //根节点到当前节点(node)的值
st1.pop();
st2.pop();
if(node->left==nullptr&&node->right==nullptr)
{
if(tmp==targetSum)
return true;
continue;
}
if(node->left)
{
st1.push(node->left);
st2.push(tmp+node->left->val); //将根节点到当前节点的和加上左孩子的和送入st2
}
if(node->right)
{
st1.push(node->right);
st2.push(tmp+node->right->val); //将根节点到当前节点的和加上右孩子的和送入st2
}
}
return false;
*/
//利用栈
stack<TreeNode*>st1;
stack<int>st2;
st1.push(root);
st2.push(root->val);
while(!st1.empty())
{
TreeNode* node=st1.top();
int tmp=st2.top();
st1.pop();
st2.pop();
if(node->left==nullptr&&node->right==nullptr)
{
if(tmp==targetSum)
return true;
continue;
}
if(node->right)
{
st1.push(node->right);
st2.push(node->right->val+tmp);
}
if(node->left)
{
st1.push(node->left);
st2.push(node->left->val+tmp);
}
}
return false;
}
};