LeetCode Path Sum 系列

题目描述

LeetCode 三道 Path Sum 的题目,给定一棵二叉树和一个路径和targetSum,分别求问:

解题思路

二叉树前序遍历。
从root到leaf的直接从root开始累计求和即可,采用回溯方式,进分支后累加本节点value,退出分支前减去本节点value;
任意祖先到子孙结点路径,需要借助从root到当前结点的路径来回溯,到达任意结点后首先判断到root的路径是否符合要求,然后检查这条路径上其他起点的路径是否满足要求;

参考代码

Path Sum

非递归,使用栈作为辅助。

/*
 * @lc app=leetcode id=112 lang=cpp
 *
 * [112] Path Sum
 */

// @lc code=start
/**
 * 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:
    bool hasPathSum(TreeNode* root, int sum) {
        // if(root == nullptr) return (sum == 0);
        if(root == nullptr) return false;
        // BFS或者DFS都可以,这里用DFS可以更快结束
        stack<pair<TreeNode*, int>> stk;
        stk.push({root, root->val});
        while(!stk.empty()) {
            auto p = stk.top();
            stk.pop();
            TreeNode* ptr = p.first;
            int psum = p.second;
            if(psum == sum && ptr->left == nullptr && ptr->right == nullptr) return true;

            if(ptr->right) stk.push({ptr->right, psum + ptr->right->val});
            if(ptr->left) stk.push({ptr->left, psum + ptr->left->val});
        }
        return false;
    }
};
// @lc code=end

Path Sum II

回溯,递归解法。

/*
 * @lc app=leetcode id=113 lang=cpp
 *
 * [113] Path Sum II
 */

// @lc code=start
/**
 * 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:
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        if (root == nullptr) return {};
        vector<vector<int>> res;
        vector<int> path;
        find(res, path, root, targetSum);
        return res;
    }
    void find(vector<vector<int>>& res, vector<int>& path, TreeNode* root, int targetSum) {
        assert(root != nullptr);
        path.push_back(root->val);
        targetSum -= root->val;

        if (root->left == nullptr && root->right == nullptr) {
            // leaf
            if (targetSum == 0) {
                res.push_back(path);
            }
            // path.clear();
            // return; // pop_back leaf at end
        }
        if (root->left) find(res, path, root->left, targetSum);
        if (root->right) find(res, path, root->right, targetSum);

        path.pop_back();
        targetSum += root->val;
    } // AC
};
// @lc code=end

Path Sum III

回溯,递归解法。

/*
 * @lc app=leetcode id=437 lang=cpp
 *
 * [437] Path Sum III
 */

// @lc code=start
/**
 * 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 == nullptr) return {};
        int res = 0;
        vector<int> path;
        find(res, path, root, sum);
        return res;
    }
    void find(int& res, vector<int>& path, TreeNode* root, int targetSum) {
        assert(root != nullptr);
        path.push_back(root->val);
        targetSum -= root->val;

        if (targetSum == 0) {
            res++;
        } // path from root to this node
        int tsum = targetSum;
        for (int i=0; i<path.size()-1; i++) {
            if ((tsum += path[i]) == 0) {
                res++;
            } // path from ancestors to this node
        }

        if (root->left) find(res, path, root->left, targetSum);
        if (root->right) find(res, path, root->right, targetSum);

        path.pop_back();
        targetSum += root->val;    
    } // AC
};
// @lc code=end
posted @ 2021-01-31 13:31  与MPI做斗争  阅读(54)  评论(0编辑  收藏  举报