I was solving the following problem on leetcode:
Given the root of a binary tree and an integer targetSum, return true if the tree has a root-to-leaf path such that adding up all the values along the path equals targetSum.
Following is the specific problem I was solving:
And following is the code I wrote, that solves this specific problem - where the targetSum
=22 (and this solution is Accepted by leetcode) :
public class TreeNode
{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val = 0, TreeNode left = null, TreeNode right = null)
{
this.val = val;
this.left = left;
this.right = right;
}
}
namespace BinaryTree
{
internal class Program
{
static void Main(string[] args)
{
TreeNode root = new TreeNode(5);
TreeNode a = new TreeNode(4);
TreeNode b = new TreeNode(11);
TreeNode c = new TreeNode(7);
TreeNode d = new TreeNode(2);
TreeNode e = new TreeNode(8);
TreeNode f = new TreeNode(13);
TreeNode g = new TreeNode(4);
TreeNode h = new TreeNode(1);
root.left = a;
root.left.left= b;
root.left.left.left = c;
root.left.left.right= d;
root.right = e;
root.right.left= f;
root.right.right= g;
root.right.right.right= h;
int targetSum = 22;
bool hasPathSum = HasPathSum(root, targetSum);
}
static bool HasPathSum(TreeNode root, int targetSum)
{
if (root == null)
return false;
int currentSum = 0;
return PathSum(root, targetSum, currentSum);
}
static bool PathSum(TreeNode root, int targetSum, int currentSum)
{
if (root == null)
return false;
currentSum += root.val;
bool lPath = PathSum(root.left, targetSum, currentSum);
bool rPath = PathSum(root.right, targetSum, currentSum);
if (root.left == null && root.right == null && currentSum == targetSum)
return true;
else if (lPath == true || rPath == true)
return true;
return false;
}
}
}
The code works fine because currentSum
is a local variable on the stack, and as each stack frame is popped out of the stack, the current value of currentSum
is also popped out of the stack and currentSum
restores to its previous value (I drew this on paper). And at the end of all recursive calls to PathSum
, the currentSum
=5 (that is, the value
of the original root
that we started with).
But a problem arises when we pass currentSum
as ref
into the method PathSum
(the same code above where currentSum
is passed by ref
is below):
static bool HasPathSum(TreeNode root, int targetSum)
{
if (root == null)
return false;
int currentSum = 0;
return PathSum(root, targetSum, ref currentSum);
}
static bool PathSum(TreeNode root, int targetSum, ref int currentSum)
{
if (root == null)
return false;
currentSum += root.val;
bool lPath = PathSum(root.left, targetSum, ref currentSum);
bool rPath = PathSum(root.right, targetSum, ref currentSum);
if (root.left == null && root.right == null && currentSum == targetSum)
return true;
else if (lPath == true || rPath == true)
return true;
return false;
}
I also drew what is happening on the stack here and, as we visit each node in the Binary Tree recursively, the line currentSum+=root.val
in the method PathSum
adds up all the values of the roots
that we have visited till now. And at the end of all the recursive calls to PathSum
, currentSum
=55 (sum of all the values of all the nodes in the binary tree).
I believe this is happening because when we pass currentSum
by ref
, we are infact passing the address of currentSum
(similar to ¤tSum
in C/C++). And since the Argument and Parameter of PathSum
is the address of currentSum
, currentSum+=root.val
keeps on adding the values
of all visited roots
to currentSum
. Is my assumption correct?
Any further light on this will be much appreciated.