Created
February 6, 2018 21:12
-
-
Save jianminchen/80b21b3cb5e9acbed3f5ad81aa0f5892 to your computer and use it in GitHub Desktop.
Binary tree at least 2 paths same sum - recursive function, base case, data structure HashSet (not Dictionary), and prune the algorithm, return early as possible.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace duplicatePathSum_Feb6_2018 | |
{ | |
/// <summary> | |
/// Problem: | |
/// Write a function that given a binary tree, returns true if at least 2 paths down the tree have the same sum. | |
/// A path is a series of nodes from the root to the leaf. | |
/// Feb. 6, 2018 | |
/// Code is updated based on the code review: | |
/// https://codereview.stackexchange.com/a/183598/123986 | |
/// </summary> | |
class Program | |
{ | |
internal class Tree | |
{ | |
public Tree Left, Right; | |
public int Value; | |
public Tree(int number) | |
{ | |
Value = number; | |
Left = null; | |
Right = null; | |
} | |
} | |
static void Main(string[] args) | |
{ | |
RunTestcase1(); | |
RunTestcase2(); | |
RunTestcase3(); | |
} | |
public static void RunTestcase1() | |
{ | |
Tree root = new Tree(3); | |
root.Left = new Tree(4); | |
root.Left.Left = new Tree(1); | |
root.Left.Right = new Tree(1); | |
Debug.Assert(CheckForDuplicatePathSums(root)); | |
} | |
public static void RunTestcase2() | |
{ | |
Tree root = new Tree(1); | |
root.Left = new Tree(3); | |
root.Right = new Tree(4); | |
Debug.Assert(!CheckForDuplicatePathSums(root)); | |
} | |
public static void RunTestcase3() | |
{ | |
Tree root = new Tree(1); | |
root.Left = new Tree(3); | |
root.Right = new Tree(4); | |
root.Left.Left = new Tree(5); | |
root.Left.Right = new Tree(1); | |
Debug.Assert(CheckForDuplicatePathSums(root)); | |
} | |
/// <summary> | |
/// name is changed | |
/// </summary> | |
/// <param name="root"></param> | |
/// <returns></returns> | |
public static bool CheckForDuplicatePathSums(Tree root) | |
{ | |
if (root == null) | |
{ | |
return false; | |
} | |
//Use of HashSet<int> is sufficient. | |
var setOfPathSums = new HashSet<int>(); | |
// flag indicating that we have found a duplicate or not | |
bool duplicateFound = false; | |
AddToPath(root, 0, setOfPathSums, ref duplicateFound); | |
return duplicateFound; | |
} | |
/// <summary> | |
/// recursive function design | |
/// </summary> | |
/// <param name="node"></param> | |
/// <param name="incomingSum"></param> | |
/// <param name="pathSums"></param> | |
/// <param name="duplicateFounded"></param> | |
private static void AddToPath(Tree node, int incomingSum, HashSet<int> pathSums, ref bool duplicateFounded) | |
{ | |
var newSum = incomingSum + node.Value; | |
// base case - if the node is leaf node | |
if (node.Left == null && node.Right == null) | |
{ | |
if (pathSums.Contains(newSum)) | |
{ | |
// we determined that the calculated sum is already present in our set. | |
duplicateFounded = true; | |
} | |
else | |
{ | |
pathSums.Add(newSum); | |
} | |
return; | |
} | |
// After we find the answer, there is no more need to check the other paths | |
if (duplicateFounded) | |
{ | |
return; | |
} | |
// recurrence | |
if (node.Left != null) | |
{ | |
AddToPath(node.Left, newSum, pathSums, ref duplicateFounded); | |
} | |
// After we find the answer, there is no more need to check the other paths | |
if (duplicateFounded) | |
{ | |
return; | |
} | |
if (node.Right != null) | |
{ | |
AddToPath(node.Right, newSum, pathSums, ref duplicateFounded); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment