Design Pattern 9: DFS | Problem: Path Sum III
This commit is contained in:
		
							parent
							
								
									0416c5fc9f
								
							
						
					
					
						commit
						39d47e2c20
					
				
							
								
								
									
										54
									
								
								9_path_sum_iii.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								9_path_sum_iii.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
			
		||||
/* Problem: https://leetcode.com/problems/path-sum-iii/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "lib_leetcode.h"
 | 
			
		||||
#include <climits>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <stack>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
int solution(TreeNode *root, const int target_sum) {
 | 
			
		||||
  if (!root)
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  int sum_paths = 0;
 | 
			
		||||
  std::vector<long long> paths_sum;
 | 
			
		||||
  std::stack<node_and_explored> dfs;
 | 
			
		||||
  dfs.push({root, false});
 | 
			
		||||
  while (dfs.size()) {
 | 
			
		||||
    auto &[node, explored] = dfs.top();
 | 
			
		||||
    int node_val = node->val;
 | 
			
		||||
    if (explored) {
 | 
			
		||||
      dfs.pop();
 | 
			
		||||
      paths_sum.pop_back();
 | 
			
		||||
      for (long long &sum : paths_sum)
 | 
			
		||||
        sum -= node_val;
 | 
			
		||||
    } else {
 | 
			
		||||
      explored = true;
 | 
			
		||||
      paths_sum.push_back(0);
 | 
			
		||||
      for (long long &sum : paths_sum) {
 | 
			
		||||
        sum += node_val;
 | 
			
		||||
        if (sum == target_sum)
 | 
			
		||||
          sum_paths++;
 | 
			
		||||
      }
 | 
			
		||||
      TreeNode *left_child = node->left, *right_child = node->right;
 | 
			
		||||
      if (right_child)
 | 
			
		||||
        dfs.push({right_child, false});
 | 
			
		||||
      if (left_child)
 | 
			
		||||
        dfs.push({left_child, false});
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return sum_paths;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
  std::cout << solution(vector_to_tree(
 | 
			
		||||
                            {10, 5, -3, 3, 2, INT_MAX, 11, 3, -2, INT_MAX, 1}),
 | 
			
		||||
                        8)
 | 
			
		||||
            << '\n'
 | 
			
		||||
            << solution(vector_to_tree({5, 4, 8, 11, INT_MAX, 13, 4, 7, 2,
 | 
			
		||||
                                        INT_MAX, INT_MAX, 5, 1}),
 | 
			
		||||
                        22)
 | 
			
		||||
            << '\n';
 | 
			
		||||
}
 | 
			
		||||
@ -20,3 +20,5 @@ add_executable(6_find_all_missing_numbers 6_find_all_missing_numbers.cpp)
 | 
			
		||||
add_executable(7_reverse_nodes_in_k_group 7_reverse_nodes_in_k_group.cpp)
 | 
			
		||||
 | 
			
		||||
add_executable(8_binary_tree_level_order_traversal 8_binary_tree_level_order_traversal.cpp)
 | 
			
		||||
 | 
			
		||||
add_executable(9_path_sum_iii 9_path_sum_iii.cpp)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										108
									
								
								lib_leetcode.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								lib_leetcode.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,108 @@
 | 
			
		||||
/* Common leetcode.com problem's scaffold code
 | 
			
		||||
 */
 | 
			
		||||
#ifndef RADII_LEETCODE
 | 
			
		||||
#define RADII_LEETCODE
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <queue>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
/* Below TreeNode definition is copied from the problem at
 | 
			
		||||
 https://leetcode.com/problems/path-sum-iii/ */
 | 
			
		||||
struct TreeNode {
 | 
			
		||||
  int val;
 | 
			
		||||
  TreeNode *left;
 | 
			
		||||
  TreeNode *right;
 | 
			
		||||
  TreeNode() : val(0), left(nullptr), right(nullptr) {}
 | 
			
		||||
  TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 | 
			
		||||
  TreeNode(int x, TreeNode *left, TreeNode *right)
 | 
			
		||||
      : val(x), left(left), right(right) {}
 | 
			
		||||
};
 | 
			
		||||
/* Above TreeNode definition is copied from the problem at
 | 
			
		||||
https://leetcode.com/problems/path-sum-iii/ */
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
struct node_and_explored {
 | 
			
		||||
  TreeNode *node;
 | 
			
		||||
  bool explored;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
std::ostream &operator<<(std::ostream &out, TreeNode *node) {
 | 
			
		||||
  out << "{";
 | 
			
		||||
  if (!node) {
 | 
			
		||||
    out << "}";
 | 
			
		||||
    return out;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::queue<TreeNode *> bfs;
 | 
			
		||||
  bfs.push(node);
 | 
			
		||||
  while (bfs.size()) {
 | 
			
		||||
    node = bfs.front();
 | 
			
		||||
    bfs.pop();
 | 
			
		||||
    if (node) {
 | 
			
		||||
      out << node->val << ", ";
 | 
			
		||||
      bfs.push(node->left);
 | 
			
		||||
      bfs.push(node->right);
 | 
			
		||||
    } else
 | 
			
		||||
      out << "null, ";
 | 
			
		||||
  }
 | 
			
		||||
  out << "\b\b}";
 | 
			
		||||
  return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T = int>
 | 
			
		||||
std::ostream &operator<<(std::ostream &out, const std::vector<T> &vec) {
 | 
			
		||||
  out << "{";
 | 
			
		||||
  if (!vec.size()) {
 | 
			
		||||
    out << "}";
 | 
			
		||||
    return out;
 | 
			
		||||
  }
 | 
			
		||||
  for (int num : vec) {
 | 
			
		||||
    std::cout << num << ", ";
 | 
			
		||||
  }
 | 
			
		||||
  out << " \b\b}";
 | 
			
		||||
  return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T = int>
 | 
			
		||||
std::ostream &operator<<(std::ostream &out,
 | 
			
		||||
                         const std::vector<std::vector<T>> &vec_2d) {
 | 
			
		||||
  out << "{";
 | 
			
		||||
  if (!vec_2d.size()) {
 | 
			
		||||
    out << "}";
 | 
			
		||||
    return out;
 | 
			
		||||
  }
 | 
			
		||||
  for (const std::vector<int> &vec : vec_2d)
 | 
			
		||||
    out << vec << ", ";
 | 
			
		||||
  out << " \b\b}";
 | 
			
		||||
  return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T = int> TreeNode *vector_to_tree(std::vector<T> &&vec) {
 | 
			
		||||
  if (!vec.size())
 | 
			
		||||
    return nullptr;
 | 
			
		||||
 | 
			
		||||
  std::vector<TreeNode *> *nodes = new std::vector<TreeNode *>;
 | 
			
		||||
  for (std::size_t i = 0, upto = vec.size(); i < upto; i++) {
 | 
			
		||||
    // NOTE: cannot use T_MAX in problem input since treating it as empty node
 | 
			
		||||
    if (vec[i] == std::numeric_limits<T>::max())
 | 
			
		||||
      nodes->emplace_back(nullptr);
 | 
			
		||||
    else
 | 
			
		||||
      nodes->emplace_back(new TreeNode(vec[i]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (std::size_t i = 0, upto = vec.size(); i < upto; i++) {
 | 
			
		||||
    if (!(*nodes)[i])
 | 
			
		||||
      continue;
 | 
			
		||||
    std::size_t left = 2 * i + 1, right = 2 * i + 2;
 | 
			
		||||
    if (left < upto)
 | 
			
		||||
      (*nodes)[i]->left = (*nodes)[left];
 | 
			
		||||
    if (right < upto)
 | 
			
		||||
      (*nodes)[i]->right = (*nodes)[right];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return (*nodes)[0];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user