leetcode-437-Path Sum III
2017-02-22 11:23
337 查看
问题
题目:[Path Sum III]思路
这个题目其实挺好的,感觉对于preOrder的理解一下又上升了一个层次。当然,这个题本身我没做出来。实际做的时候,只能说做出了一部分。
还是对于遍历这件事本省立即的不充分。还有对于递归的语义没有想清楚。
这到题麻烦的一点是说:不一定从根节点开始,你可以从任意节点。只要是从它开始字段和为sum即可。
那这个题的解法不就是,遍历每一个点,然后从每一节点开始寻找和为sum的子段。这个思路是没有问题的。就是一道遍历的问题。
然后,visit的实现非诚清晰。
然后,主函数语义是什么?这个我一直想的不是很明白
还是要对树的遍历语义充分理解就明白了。
想一想最基本的遍历:
void preOrder(TreeNode* root){ if(!root) return; else{ visit(root); preOrder(root->left); preOrder(root->right); } }
遍历一棵树,可以划分为三个子问题。
访问root节点
遍历左子树
遍历右子树
那么同样的,对于pathSum(root, target)的语义:查找以root为根但不见得以root开始的和为target的路径。
可以划分为三个子问题。
以root开始和为target的路径
查找以root->left为根但不见得以root->left开始的和为target的路径。
查找以root->right为根但不见得以root->right开始的和为target的路径。
这样语义不就顺了,我第一次之所以错,就是因为语义的事我没想清楚。换个角度,如果你在pathSum递归调用的时候,缩小了target的规模,那么你再调用一层的时候,从子节点开始就不是寻找和为target的节点了。这样显然就不对了。
这个题不错,加深了对递归的理解,这个题没有对target缩减规模,但是树的深度还是缩减了。
代码
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: int pathSum(TreeNode* root, int sum) { if(!root) return 0; else{ int ans = 0; ans += visit(root, sum); ans += pathSum( root->left, sum ); ans += pathSum( root->right, sum ); return ans; } } private: int visit(TreeNode* root, int target){ if(!root) return 0; else{ int ans = 0; if(root->val == target) ++ans; ans += visit(root->left, target-root->val); ans += visit(root->right, target-root->val); return ans; } } };
思路1
方法没区别,又写了一遍。代码1
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: int pathSum(TreeNode* root, int sum) { if(!root) return 0; int ans = 0; dfs(root, sum, ans); return ans; } private: void dfs(TreeNode* root, int target, int& ans){ if(!root) return; visit(root, 0, target, ans ); dfs(root->left, target, ans); dfs(root->right, target, ans); } void visit(TreeNode* root, int cur_sum, int target, int& ans){ if(!root) return; cur_sum += root->val; if(cur_sum == target) ++ans; visit(root->left, cur_sum, target, ans); visit(root->right, cur_sum, target, ans); } };
思路1
又写了一遍。注意一点就好,对于pathSum从左右枝走的时候,还是要判断路径和为sum。
对于问题的缩减是在visit的时候。
代码
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: int pathSum(TreeNode* root, int sum) { if(!root) return 0; int ret = 0; ret += visit(root, sum); ret += pathSum(root->left, sum); ret += pathSum(root->right, sum); return ret; } private: int visit(TreeNode* root, int sum){ if(!root) return 0; int ans = 0; if(root->val == sum) ++ans; ans += visit(root->left, sum-root->val); ans += visit(root->right, sum-root->val); return ans; } };
思路2
这个题的思路我是有的,这个题其实也是遍历。只不过每次遍历的visti又是一个遍历。
注意以下两个接口的区别:
dfs当中的root,代表从以这个root开始的子树当中,存在的所有路径和为target的路径,也就是说从这个root子树的任何一个节点都可能是一条全新的path。
但是,visit接口当中的path,表明的就是以当前root开始的path。
前面的代表整个root子树当中,所有根节点开始的path,而后者只是一个root的path。
4000
再说一遍,前者的root子树当中的每一个节点都可以开始一条path,而后者root代表就是从该root开始的一条path.
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: int pathSum(TreeNode* root, int sum) { if(!root) return 0; int ans = 0; dfs(root, sum, ans); return ans; } private: void dfs(TreeNode* root, int target, int& ans){ if(root){ visit( root, 0, target, ans); dfs( root->left, target, ans ); dfs( root->right, target, ans ); } } private: void visit(TreeNode* root, int cur, int target, int& ans){ if(root){ cur += root->val; if( cur == target ) ++ans; visit(root->left, cur, target, ans); visit(root->right, cur, target, ans); } } };
相关文章推荐
- LeetCode 437 Path Sum III 题解
- LeetCode "437. Path Sum III"
- [python]leetcode(437). Path Sum III
- LeetCode 437 Path Sum III (DFS)
- LeetCode 437 Path Sum III
- leetcode(437):Path Sum III
- leetcode[437] PathSum III 个人题解
- LeetCode 437 Path Sum III
- 437. Path Sum III
- LeetCode 437. Path Sum III 题解 和固定的二叉树路径数目
- 437. Path Sum III
- 【LeetCode】#112 #113 #437 Path Sum Series
- LeetCode No.437 Path Sum III
- LeetCode笔记:437. Path Sum III
- LeetCode 437. Path Sum III
- [LeetCode]437. Path Sum III
- 437. Path Sum III
- 437. Path Sum III
- 【LeetCode】 437. Path Sum III
- Leetcode Path Sum III