当一个思路要求的越来越多,办法越想越古怪,甚至需要你纠结是否违反某些编码常识的时候。你应该意识到,这条路可能走错了。
别急着继续另一条路,而是回头看看走过的路,看着你来时的方向,也许希望就在那里。
这道题就是明证,我以非常常规的思路,决定用回溯法探路,但回溯有个硬伤,就是要记录路径,在这里就是要记录父节点与权值。(权值在这里指的是到这个节点的sum)
好,我可以弄个栈,但是一个比较古怪的数据结构: std::stack<std::pair<TreeNode*, int>>
。这也还在能接受的范围。
忽然发现不可行,栈里放的权值,怎么计算?每一层都去累加?累加的中间结果放在哪?
习惯性的看看参数,咦,直接把 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 行。。。