有关剑指offer题目的解析:剑指offer 题目整理
题目要求
输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
解题分析
这类题目是典型的深度优先遍历类型的试题,我们通过结合前序遍历算法来解题。
给出如下一棵二叉树,返回和为22的路径。首先我们先进行前序遍历,依次到节点4,由于它是叶子结点,所以计算他的路径值为19不是22所以这条路就不是我们要寻找的,所以从叶子结点退回到父节点,然后到其右孩子节点继续进行DFS遍历任务,找到就返回路径,没有就继续递归遍历。
10
/ \
5 12
/ \
4 7
注意点: 由叶子结点退回到父节点的时候,为了不干扰后面的操作,这里一定要删去当前节点,比如在左孩子节点(‘4’)返回父节点(‘5’)进行右孩子(‘7’)递归的时候,需要先把左孩子(‘4’)删除,确保我们后续的操作是正确的。
主要代码c++
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
vector<vector<int>> resPath;
vector<int> eachPath;
if(root)
DfsFindEachPath(root,expectNumber,resPath,eachPath);
return resPath;
}
private:
void DfsFindEachPath(TreeNode* pRoot, int expectNumber, vector<vector<int>>&resPath, vector<int>&eachPath)
{
eachPath.push_back(pRoot->val);
if(pRoot->left == nullptr && pRoot->right == nullptr) // 到叶子结点了就判断路径是否符合
{
if(pRoot->val == expectNumber) // 每一步的expectNumber都会变 最后会等于叶子结点的值
resPath.push_back(eachPath);
}
// 非叶子结点就继续DFS搜索遍历 注意每步的expectNumber都是变的
if(pRoot->left)
DfsFindEachPath(pRoot->left, expectNumber - pRoot->val, resPath, eachPath);
if(pRoot->right)
DfsFindEachPath(pRoot->right, expectNumber - pRoot->val, resPath, eachPath);
eachPath.pop_back(); // 这一步为了返回父节点的时候,删除当前路径上的点
}
};
总结
这是典型的使用带有记忆的深度优先遍历方法,递归处理左右孩子,一定要记住哈,很有用。