2014-03-19 05:07
题目:给定一棵二叉树T和一个值value,在T中找出所有加起来和等于value的路径。路径的起点和终点都可以是树的任意节点。
解法:我偷了个懒,直接把这棵树看成一个无向图,用DFS来进行暴力搜索解决问题。因为没有什么数据顺序或是范围的限制,所以搜索剪枝好像也不太容易。
代码:
1 // 4.9 Find all paths in a binary tree, the path doesn't have to start or end at the root or a leaf node. 2 #include <cstdio> 3 #include <unordered_map> 4 #include <unordered_set> 5 using namespace std; 6 7 struct TreeNode { 8 int val; 9 TreeNode *left; 10 TreeNode *right; 11 12 TreeNode(int _val = 0):val(_val), left(nullptr), right(nullptr) {}; 13 }; 14 15 void constructTree(TreeNode *&root) 16 { 17 int val; 18 19 scanf("%d", &val); 20 if (val == 0) { 21 root = nullptr; 22 } else { 23 root = new TreeNode(val); 24 constructTree(root->left); 25 constructTree(root->right); 26 } 27 } 28 29 void constructGraph(TreeNode *root, unordered_map<TreeNode *, unordered_set<TreeNode *> > &graph) 30 { 31 if (root->left != nullptr) { 32 graph[root].insert(root->left); 33 graph[root->left].insert(root); 34 constructGraph(root->left, graph); 35 } 36 37 if (root->right != nullptr) { 38 graph[root].insert(root->right); 39 graph[root->right].insert(root); 40 constructGraph(root->right, graph); 41 } 42 } 43 44 void DFS(TreeNode *node, vector<TreeNode *> &path, int sum, const int target, 45 unordered_set<TreeNode *> &checked, 46 unordered_map<TreeNode *, unordered_set<TreeNode *> > &graph, vector<vector<TreeNode *> > &result) 47 { 48 path.push_back(node); 49 checked.insert(node); 50 51 if (sum == target) { 52 result.push_back(path); 53 } 54 unordered_set<TreeNode *>::iterator it; 55 for (it = graph[node].begin(); it != graph[node].end(); ++it) { 56 if (checked.find(*it) == checked.end()) { 57 DFS(*it, path, sum + (*it)->val, target, checked, graph, result); 58 } 59 } 60 61 checked.erase(node); 62 path.pop_back(); 63 } 64 65 void doDFS(TreeNode *root, vector<TreeNode *> &path, const int target, 66 unordered_set<TreeNode *> &checked, 67 unordered_map<TreeNode *, unordered_set<TreeNode *> > &graph, vector<vector<TreeNode *> > &result) 68 { 69 path.clear(); 70 checked.clear(); 71 DFS(root, path, root->val, target, checked, graph, result); 72 if (root->left != nullptr) { 73 doDFS(root->left, path, target, checked, graph, result); 74 } 75 if (root->right != nullptr) { 76 doDFS(root->right, path, target, checked, graph, result); 77 } 78 } 79 80 void clearTree(TreeNode *&root) 81 { 82 if (root == nullptr) { 83 return; 84 } 85 86 if (root->left != nullptr) { 87 clearTree(root->left); 88 } 89 if (root->right != nullptr) { 90 clearTree(root->right); 91 } 92 delete root; 93 root = nullptr; 94 } 95 96 int main() 97 { 98 int i, j; 99 int target; 100 TreeNode *root; 101 unordered_map<TreeNode *, unordered_set<TreeNode *> > graph; 102 unordered_map<TreeNode *, unordered_set<TreeNode *> >::iterator it; 103 unordered_set<TreeNode *> checked; 104 vector<TreeNode *> path; 105 vector<vector<TreeNode *> > result; 106 107 while (true) { 108 constructTree(root); 109 if (root == nullptr) { 110 break; 111 } 112 constructGraph(root, graph); 113 while (scanf("%d", &target) == 1 && target) { 114 doDFS(root, path, target, checked, graph, result); 115 if (result.empty()) { 116 printf("No path is found.\n"); 117 } else { 118 for (i = 0; i < (int)result.size(); ++i) { 119 printf("%d", result[i][0]->val); 120 for (j = 1; j < (int)result[i].size(); ++j) { 121 printf("->%d", result[i][j]->val); 122 } 123 result[i].clear(); 124 printf("\n"); 125 } 126 result.clear(); 127 } 128 path.clear(); 129 checked.clear(); 130 } 131 for (it = graph.begin(); it != graph.end(); ++it) { 132 (it->second).clear(); 133 } 134 graph.clear(); 135 clearTree(root); 136 } 137 138 return 0; 139 }