zoukankan      html  css  js  c++  java
  • 437. Path Sum III

    今天继续刷leetcode呀!

    这道题是leetcode 第437题 Path Sum III ,这道题意思是找出一棵二叉树中所有从上往下的路径,这些路径中的结点的权值之和等于题目给定的target。这里有一个要求,就是路径的起点不需要是整棵二叉树的根结点,路径的终点也不需要是叶子结点。只要是从上往下的路径就行,当然也不能包含重复结点。

    这个问题既然是二叉树的,那么一般是用递归的方式来做。

    直接分析该问题会发现,路径的终点不确定好说,因为递归就是从整棵树的起点出发,依次往下进行的,我们可以在递归到某个结点的时候判断当前路径符不符合要求,符合要求的话就添加到结果中。

    但是递归起点不确定可不好做,所以,我们先把这道题转变一下,其他条件不变,仅要求路径的起点是整棵树的根结点,于是我们可以写出如下代码:

    /**
     * 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:
        int pathSum(TreeNode* root, int sum) {
            if (!root) return 0;
            vector<int> path;
            int cnt = 0;
            helper(root, sum, 0, path, cnt);
            return cnt;
        }
    
        void helper(TreeNode* root, int sum, int out, vector<int>& path, int& cnt) {
            if (root) {
                path.push_back(root->val);
                out += root->val;
                if (out == sum) cnt++;
    
                helper(root->left, sum, out, path, cnt);
                helper(root->right, sum, out, path, cnt);
    
                path.pop_back();
            }
        }
    };
    

    这个应该没啥问题,很多人做到这里不会做了,因为一看起点不固定怎么办?如果你去想着改造一下helper函数来达到原问题的要求那大概是有点难。

    这里我们有个技巧,就是改造一下原始函数,你想一下,对于某个结点,我们可以从它开始寻找符合要求的路径,也可以从它下面的孩子结点开始寻找,于是,我们简单修改一下pathSum函数就可以达到原问题要求

    /**
     * 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:
        int pathSum(TreeNode* root, int sum) {
            if (!root) return 0;
    
            vector<int> path;
            int cnt = 0;
            helper(root, sum, 0, path, cnt);
            return cnt + pathSum(root->left, sum) + pathSum(root->right, sum);
        }
    
        void helper(TreeNode* root, int sum, int out, vector<int>& path, int& cnt) {
            if (root) {
                path.push_back(root->val);
                out += root->val;
                if (out == sum) cnt++;
    
                helper(root->left, sum, out, path, cnt);
                helper(root->right, sum, out, path, cnt);
    
                path.pop_back();
            }
        }
    };
    

    看到每,pathSum 本身也是一个递归函数,它的返回值应该包括三部分,从当前结点出发找到的路径数量,从它的左右孩子出发找到的路径数量,这个地方确实需要一点技巧,就是本身是递归函数,然后其中又调用另外一个递归函数,和单纯的dfs形式上还是有点区别的。

    只有0和1的世界是简单的
  • 相关阅读:
    仿msn风格的选项卡_网页代码站(www.webdm.cn)
    拍拍网头部导航菜单_网页代码站(www.webdm.cn)
    横向滑动特效的菜单(js+css)_网页代码站(www.webdm.cn)
    QuickMenu 超强悍菜单_网页代码站(www.webdm.cn)
    紫罗兰风格的导航条_网页代码站(www.webdm.cn)
    兼容性超强的六级网站导航主菜单_网页代码站(www.webdm.cn)
    用JavaScript实现横向滑出的多级竖向菜单_网页代码站(www.webdm.cn)
    一款溢出式侧边栏导航菜单_网页代码站(www.webdm.cn)
    css打造的又一款清新的横排下拉菜单_网页代码站(www.webdm.cn)
    [ZZ]byte[]到short、int、long的相互转换
  • 原文地址:https://www.cnblogs.com/nullxjx/p/14364511.html
Copyright © 2011-2022 走看看