LeetCode - Path Sum I、II、III、IV - 深度优先遍历

本篇文章记录 Path Sum 相关的四道题目:

112 - Path Sum - Easy

113 - Path Sum II - Medium

437 - Path Sum III - Easy

666 - Path Sum IV - Medium

Path Sum I

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.   Note:  A leaf is a node with no children.

Example: Given the below binary tree and sum = 22,

      5
     / \
    4   8
   /   / \
  11  13  4
 /  \      \
7    2      1

return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.

解: 正常的深度优先遍历,每次记录目前的和,当到达叶子节点且和正好为sum是返回true。(其实curSum这个变量可以不用,用人,remain记录还剩多少达到sum也行)。

bool dfs(int curSum, TreeNode* nod, const int& sum)
{
    if(!nod) return false;
    curSum += nod->val;
    if(!nod->left && !nod->right && curSum == sum) return true;
    return dfs(curSum, nod->left, sum) || dfs(curSum, nod->right, sum);
}
bool hasPathSum(TreeNode* root, int sum) {
    return dfs(0, root, sum);
}

Path Sum II

Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.

Note: A leaf is a node with no children.

Example:   Given the below binary tree and sum = 22,

      5
     / \
    4   8
   /   / \
  11  13  4
 /  \    / \
7    2  5   1

Return:

[   [5,4,11,2], [5,8,4,5]   ]

解: 这道题相当于上边的题目多了一个记录路径的要求,且因为不是找到就返回,所以需要记录所有路径。

vector<vector<int>> res;
void dfs(TreeNode* nod, vector<int> tmp, int remain)
{
    if(!nod->left && !nod->right && nod->val == remain)
    {
        tmp.push_back(nod->val);
        res.push_back(tmp);
        return;
    }
    tmp.push_back(nod->val);
    if(nod->left)  dfs(nod->left,  tmp, remain - nod->val);
    if(nod->right) dfs(nod->right, tmp, remain - nod->val);
}
vector<vector<int>> pathSum(TreeNode* root, int sum) {
    if(!root) return vector<vector<int>>();
    else      dfs(root, vector<int>(), sum);
    return res;
}

Path Sum III

Find the number of paths that sum to a given value. The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes). The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8

      10
     /  \
    5   -3
   / \    \
  3   2   11
 / \   \
3  -2   1

Return 3. The paths that sum to 8 are:

1.  5 -> 3
2.  5 -> 2 -> 1
3. -3 -> 11

解:这次求和的路径不需要从头到尾了,只要在树里,从上向下,一条路径上和为sum,就要记录。这道题虽然是easy,但是比较有意思,就是在从每个节点向下找的dfs中,用到递归,然后pathSum这个函数又用到了递归,还是比较有意思的。需要注意的就是,在和为sum的时候,因为有负数的存在,所以还需要继续向下遍历,看会不会出现新的和为sum的更长的路径。

int dfs(TreeNode* nod, int remain)
{
    if(!nod) return 0;
    remain -= nod->val;
    return (remain == 0) + dfs(nod->left, remain) + dfs(nod->right, remain);
}
int pathSum(TreeNode* root, int sum) {
    if(!root) return 0;
    else return dfs(root, sum) + pathSum(root->left,  sum) + pathSum(root->right, sum);
}

Path Sum IV

If the depth of a tree is smaller than 5, then this tree can be represented by a list of three-digits integers.

For each integer in this list:

  • The hundreds digit represents the depth D of this node, 1 <= D <= 4.
  • The tens digit represents the position P of this node in the level it belongs to, 1 <= P <= 8. The position is the same as that in a full binary tree.
  • The units digit represents the value V of this node, 0 <= V <= 9.
  • Given a list of ascending three-digits integers representing a binary with the depth smaller than 5. You need to return the sum of all paths from the root towards the leaves.

Example 1 :   Input: [113, 215, 221]     Output: 12
Explanation:   The tree that the list represents is:
    3
   / \
 5   1

The path sum is (3 + 5) + (3 + 1) = 12.

Example 2 :    Input: [113, 221]             Output: 4
Explanation:    The tree that the list represents is: 
    3
     \
      1

The path sum is (3 + 1) = 4.

解: 第一个例子中,113表示,第,1层第1个位置是3,215表示,第2层第1个位置是5,221表示,第2层第2个位置是1。理解了这个这道题就很容易了,就是正常的二叉树求所有路径上和的总和。

    因为没钱没有premium,没法提交,但是看起来不难。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值