0

"Given a Binary Tree and an integer number k. Write a function to print every path in the tree that sum of the nodes in the path is k. Assume a path can start from any node and end at any node, i.e. they need not be root node and leaf node; and negative numbers can also be there in the tree."

I'm still stuck on the logic behind traversing a tree to achieve this goal. Any assistance/hints would be extremely appreciated!

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
C. Lee
  • 59
  • 1
  • 6
  • Pure code-writing requests are off-topic on Stack Overflow -- we expect questions here to relate to *specific* programming problems -- but we will happily help you write it yourself! Tell us [what you've tried](http://stackoverflow.com/help/how-to-ask), and where you are stuck. This will also help us answer your question better. – Tatsuyuki Ishi Mar 14 '17 at 02:55
  • `"Any assistance/hints would be extremely appreciated!"` One hint I could offer is that you grab a good book on datastructures and read it. – Vada Poché Mar 14 '17 at 03:00
  • 1
    Actually, your question is an exact duplicate of http://stackoverflow.com/questions/11328358/algorithm-to-print-all-paths-with-a-given-sum-in-a-binary-tree . – synchronizer Mar 14 '17 at 03:03
  • You can make a "scan_branch" recursive function that takes "distance so far" and a node to scan.Use scan_branch on the left and right nodes (if not null) from your starting node, they then call scan_branch on their children and so on, adding the node distance as they go. After scanning all children from the current node, you move up to your parent, add in the node value,then scan_branch on scan_branch function. When you move up remember which node you came from so you don't backtrack.When you find a hit however, you need to print the path.Adding to a local "path string" as you go would be best – Jason Lang Mar 14 '17 at 03:10

1 Answers1

2

logic behind traversing a tree to achieve this goal

Use either Depth First or Breadth First search to visit each node in the tree.

Start a new search at each node.

Because this tree is a recursive data structure, I would use recursion to perform search.

and end the recursion: - update 03/14

1) at the leaf node.

NOT when target sum is found, because negative values exist

NOT when when sum exceeds target sum, because negative values exist

Note: I think this simplifies the 'summing' action a lot. It is now a DF search terminating at the leafs with simple output at specific nodes.

NO 'decurse' actions are required, as all branches will be explored by DF/BF visit.


update 3/18

Some sample outputs from my code.

An 'on-its-side' tree display (top-to-the-left)

               '-3' 
          '-2' 
               '-1' 
     '0' 
               '1' 
          '2' 
                    '3' 
               '4' 
'5' 
               '6' 
          '7' 
                    '8' 
               '9' 
     '10' 
               '11' 
          '12' 
                    '13' 
               '14' 
                    '42' 

Sample 'targetSum' findings: (5 of 41)

BTree_t::dfVisit(-2)  
  start level 3:    -2 
  start level 2:     0   -2 

BTree_t::dfVisit(-1)  
  start level 4:    -1 

BTree_t::dfVisit(0)  
  start level 2:     0 
  start level 1:     5    0   -2   -3 

BTree_t::dfVisit(1)  
  start level 4:     1

update 2017/03/22

There are plenty of examples of depth-first-searches code on the web. In my approach, the tree contribution is simply to start the search at the root (or explain why it can't).

// depth-first-visit of all nodes in tree
void BTree_t::dfVisitSum(const int targetSum)
{
   std::cout << "\n\n  BTree_t::dfVisitSum(" << targetSum << ") ";

   if(m_root)
   {
      int reportCount = m_root->dfVisitSum(targetSum);
      if(0 == reportCount)
         std::cout << "none";
    }
    else
    {
      std::cerr << "\n  dfVisitSum() Note: tree has no elements.."
                << std::endl;
   }
}

If we now look at the node dfVisitSum(), we note it has a limited duration 'nodeLog' passed into the sumSearch():

// depth-first-visit of all nodes below the current node
int Node_t::dfVisitSum(const int targetSum)
{
   int reportCount = 0;

   // dfs search left, then do something, then search right
   if(m_left)  {  reportCount += m_left->dfVisitSum(targetSum); }

   {
      // while visiting this node, create a vector for logging 
      NVec_t  nodeLog;   
      nodeLog.reserve(nodeDepthMax()); 

      // start a new depth-first-search called "sumSearch()
      reportCount += sumSearch(targetSum, nodeLog);  

   }  // nodeLog terminates here

   if(m_right) { reportCount += m_right->dfVisitSum(targetSum); }

   return (reportCount);
}

Finally,

// target-sum-search
int Node_t::sumSearch(const int targetSum, NVec_t& nodeLog)
{
   int reportCount = 0;

   // capture visit of this node to log
   nodeLog.push_back(this); 

   // in dfs style, first search down the left 
   if(m_left)  {  reportCount += m_left->sumSearch(targetSum, nodeLog); }

   { // now do something in this node
      size_t   startLvl = nodeLog[0]->m_lvl; // for report

      int accumulateSum = 0;
      for (size_t i = 0; i < nodeLog.size(); ++i)
         accumulateSum += nodeLog[i]->m_payLoad;
      // sure, sure, use std::accumulate with a lambda, if you wish

      if (targetSum == accumulateSum)
      {
         std::stringstream reportLabelSS; // convenience
         reportLabelSS << "\n     @ level " << startLvl << ":";
         std::cout << showNVec(nodeLog, reportLabelSS.str());
         // this output displays start level and nodes-visited payloads
         reportCount += 1;  // report occurrence north bound to caller
      }
   }
   // in dfs style, search down the right
   if(m_right) { reportCount += m_right->sumSearch(targetSum, nodeLog); }

   // discard / clear  this node visit from log, we are out-a-here
   nodeLog.pop_back(); // removes last nodeLog element
   return(reportCount); // report count
}
2785528
  • 5,438
  • 2
  • 18
  • 20
  • Re: "[...] ending the recursion [...] 2) when sum exceeds target sum": That doesn't work, because the question specifies that there can be negative numbers in the tree. – ruakh Mar 14 '17 at 03:59
  • @ruakh - Thanks, I missed that. Hmmm, now I suppose that when target sum is found (case 1), the recursion also should not end. So only (case 3) should be implemented ... always spin to leaf termination. – 2785528 Mar 14 '17 at 19:51
  • oops - typedef std::vector NVec_t; – 2785528 Mar 22 '17 at 21:39
  • showNVec (nodeLog, std::string) output example already provided. See "Sample 'targetSum' findings: (5 of 41)" above. – 2785528 Mar 22 '17 at 21:44