leetcode-112-Path Sum

问题

题目:[Path Sum]

思路

下面的代码并不是原始问题的代码。而是改良后的问题。即求一条路径和为sum。要求必须从根开始,但是不一定到叶子结束。
下面用到了回溯法,我觉得这题也是回溯法比较好的实现。
回溯法肯定用到了“剪枝”,但他的关键是要回溯到上一个状态。

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool hasPathSum(TreeNode* root, int sum) {
        if(!root) return false;
        int ans = 0;
        bool found = false;
        dfs( root, sum, ans, found);
        return found;
    }
private:
    void dfs(TreeNode* root, int sum, int& ret, bool& found){
        if(root&&!found){
            ret += root->val;
            if(ret == sum){ found = true; return;}
            else if( ret > sum ){
                ret -= root->val;  // backtrace
                return ;
            }
            else{
                dfs(root->left, sum, ret, found);
                dfs(root->right, sum, ret, found);
            }
        }
    }
};

或者其实你没必要这么写,睡了一晚上发现。这也不算回溯。就是参数传递的时候。不要传递引用了。

代码1

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool hasPathSum(TreeNode* root, int sum) {
        if(!root) return false;
        int ans = 0;
        bool found = false;
        dfs( root, sum, ans, found);
        return found;
    }
private:
    void dfs(TreeNode* root, int sum, int ret, bool& found){
        if(root&&!found){
            ret += root->val;
            if(ret == sum){ found = true; return;}
            else if( ret > sum ) return;
            else{
                dfs(root->left, sum, ret, found);
                dfs(root->right, sum, ret, found);
            }
        }
    }
};

思路(本题)

因为要访问到最底层,所以到叶子的时候判断一下就行了。

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool hasPathSum(TreeNode* root, int sum) {
        if(!root) return false;
        int ans = 0;
        bool found = false;
        dfs( root, sum, ans, found);
        return found;
    }
private:
    void dfs(TreeNode* root, int sum, int ret, bool& found){
        if(root && !found){
            ret += root->val;
            if(!root->left && !root->right){
                if(ret==sum) found = true;
                return;
            }
            dfs( root->left, sum, ret, found );
            dfs( root->right, sum, ret, found );
        }
    }
};

思路2

纯递归,也是如果非要到空采取判断。需要对左右子树的情形均判断。
其实,我这种办法也相当于是判断叶子。不要到空再判断。

这道题的特点是,因为必须要到叶子。所以,要判断不是叶子的情形,以及刚好叶子边界的情形。

代码2

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool hasPathSum(TreeNode* root, int sum) {
        if(!root) return false;
        if(!root->left && !root->right) return root->val==sum;
        else if(root->left&&!root->right) return hasPathSum(root->left, sum-root->val);
        else if(!root->left&&root->right) return hasPathSum(root->right, sum-root->val);
        else return hasPathSum(root->left, sum-root->val)||hasPathSum(root->right, sum-root->val);
    }

};

思路3

这个题目,今天再次考虑,有新的收货。
对于这个题目,不放考虑一个类似的题目,其实他们都是一个题目。

如何判断一个二叉树当中是否存在值为1的叶子?
思路:基本的思路很容易考虑,dfs遍历就可以了,首先要判断是不是叶子,如果是再判断它的值是否为1,如果是1,直接返回true即可。但是,问题是,何时返回false.
我起初的思路是,整个遍历完之后,如果前面没有返回true.那么现在该返回false了。可是,这是个递归函数,什么时候才是最后运行完的时机呢?

所以,上面的思路不正确。因为这不是递归解决问题的思路,递归的思路应该是找到原问题和子问题的关系。特别需要注意的时边界条件的情况。如果,不好划分原问题和子问题,那么可以考虑简单的例子,来让抽象问题形象化。
考虑这个二叉树,[1],这个节点是叶子,是1,返回true.
[2],这个节点是叶子,是2,返回false.
[6,1,2],原问题来说,由于6不是叶子,所以问题变成左右两颗子树当中是否存在值为1的叶子,此时问题变成上面的两种情形。
这样问题就很明确了,递归主要是考虑清楚原问题和子问题的关系,然后是边界条件要处理好。如果边界不好写,就考虑一个简单例子,就是只有一层递归的情形。便于想出结果来。
代码如下:

代码3

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool hasPathSum(TreeNode* root, int sum) {
        if(!root) return false;

        if( !root->left && !root->right )
            return root->val == sum;
        else
            return hasPathSum(root->left, sum-root->val) || hasPathSum(root->right, sum-root->val);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值