diff --git a/49. Path Sum/README.md b/49. Path Sum/README.md new file mode 100644 index 0000000..a17698d --- /dev/null +++ b/49. Path Sum/README.md @@ -0,0 +1,29 @@ +当一个思路要求的越来越多,办法越想越古怪,甚至需要你纠结是否违反某些编码常识的时候。你应该意识到,这条路可能做错了。 + +别急着上另一条路,而是回头看看走过的路,看着你来时的方向,也许希望就在那里。 + +----- + +这道题就是明证,我以非常常规的思路,决定用回溯法探路,但回溯有个硬伤,就是要记录路径,在这里就是要记录,父节点与权值。(权值在这里指的是到这个节点的sum) + +好,我可以弄个栈,记录一个比较古怪的数据结构: `std::stack>`。这也还属于能接受的范围。 + +忽然发现不可行,栈里放的权值,怎么计算?每一层都去累加?累加的中间结果放在哪? + +习惯性的看看参数,咦,直接把 `root->val` 的值改为记录权值吧? + +是的,邪恶的想法就是如此诞生的,为了求得一个 bool,即是否可行,就要修改原有数据。到这里,常规思路已经有些得不偿失。 + +这时,我"回头"了,**既然累加走不通,依次减行不行**,我把注意力集中到了根节点,并重新审视了题目。 + +要求的是: + + hasPathSum(root, sum) + +我们往下减一减呢?惊奇的发现了这么一个等式: + + hasPathSum(root, sum) = hasPathSum(root->left, sum-root->val) or hasPathSum(root->right, sum-root->val); + +擦,递归!!!这么自然的思路,竟然不是优先想到的。太完美了。 + +嗯,说好的 Easy 题不需要超过 5 行,早该意识到不对的, 这道题才 3 行。。。 diff --git a/49. Path Sum/TEST.cc b/49. Path Sum/TEST.cc new file mode 100644 index 0000000..ca21fdc --- /dev/null +++ b/49. Path Sum/TEST.cc @@ -0,0 +1,34 @@ +#define CATCH_CONFIG_MAIN +#include "../Catch/single_include/catch.hpp" +#include "solution.h" + +TEST_CASE("Path Sum", "[hasPathSum]") +{ + TreeNode root(5); + TreeNode node1(4); + TreeNode node2(8); + TreeNode node3(11); + TreeNode node4(13); + TreeNode node5(4); + TreeNode node6(7); + TreeNode node7(2); + TreeNode node8(1); + + root.left = &node1; + root.right = &node2; + node1.left = &node3; + node2.left = &node4; + node2.right = &node5; + node3.left = &node6; + node3.right = &node7; + node5.right = &node8; + + Solution s; + REQUIRE( s.hasPathSum(&root, 22) == true ); + REQUIRE( s.hasPathSum(&root, 18) == true ); + REQUIRE( s.hasPathSum(&root, 30) == false ); +} + + + + diff --git a/49. Path Sum/solution.h b/49. Path Sum/solution.h new file mode 100644 index 0000000..360322a --- /dev/null +++ b/49. Path Sum/solution.h @@ -0,0 +1,16 @@ +#include +struct TreeNode { + int val; + TreeNode *left; + TreeNode *right; + TreeNode(int x) : val(x), left(NULL), right(NULL) {} +}; + +class Solution { +public: + bool hasPathSum(TreeNode *root, int sum) { + if (!root) return false; + if (!root->left and !root->right and sum-root->val==0) return true; + return hasPathSum(root->left, sum-root->val) or hasPathSum(root->right, sum-root->val); + } +};