力扣数据结构14天学习计划day12

力扣226

力扣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—路径总和

力扣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;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心之所向便是光v

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值