1. 程式人生 > >LeetCode - Path Sum I、II、III、IV - 深度優先遍歷

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,沒法提交,但是看起來不難。