此题的大框架是使用先序遍历
算法类似于栈的过程
使用了递归,递归本身的过程类似于栈。最后的pop是因为如果当前节点不是路径中的点或者路径已经找到,要把该节点弹出。
剑指offer中求的是从根节点到叶子节点的路径。
#include<iostream>
#include<vector>
using namespace std;
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
void FindPath(BinaryTreeNode* pRoot, int expectedSum, vector<int>&path, int currentSum);
void FindPath(BinaryTreeNode* pRoot, int expectedSum)
{
if (pRoot == nullptr || expectedSum == 0)
return;
vector<int> path;
int currentSum = 0;
FindPath(pRoot, expectedSum, path, currentSum);
}
void FindPath(BinaryTreeNode* pRoot, int expectedSum, vector<int>&path, int currentSum)
{
currentSum += pRoot->m_nValue;
path.push_back(pRoot->m_nValue);
bool isLeaf = pRoot->m_pLeft == nullptr && pRoot->m_pRight == nullptr;
if (currentSum == expectedSum && isLeaf)
{
vector<int>::iterator iter = path.begin();
for (; iter != path.end(); ++iter)
cout << *iter << " ";
cout << endl;
}
if (pRoot->m_pLeft != nullptr)
FindPath(pRoot->m_pLeft, expectedSum, path,currentSum );
if (pRoot->m_pRight != nullptr)
FindPath(pRoot->m_pRight, expectedSum, path, currentSum);
//在返回父亲节点之前,在路径上删除当前节点
path.pop_back();
}
void creatTree(BinaryTreeNode* root, BinaryTreeNode* left, BinaryTreeNode* right)
{
root->m_pLeft = left;
root->m_pRight = right;
}
int main()
{
/* 树
root1(1)
a(2) b(3)
c(4) d(5) e(6) f(7)
*/
BinaryTreeNode* root1 = new BinaryTreeNode();
root1->m_nValue = 1;
root1->m_pLeft = nullptr;
root1->m_pRight = nullptr;
BinaryTreeNode* a = new BinaryTreeNode();
a->m_nValue = 2;
a->m_pLeft = nullptr;
a->m_pRight = nullptr;
BinaryTreeNode* b = new BinaryTreeNode();
b->m_nValue = 3;
b->m_pLeft = nullptr;
b->m_pRight = nullptr;
BinaryTreeNode* c = new BinaryTreeNode();
c->m_nValue = 4;
c->m_pLeft = nullptr;
c->m_pRight = nullptr;
BinaryTreeNode* d = new BinaryTreeNode();
d->m_nValue = 5;
d->m_pLeft = nullptr;
d->m_pRight = nullptr;
BinaryTreeNode* e = new BinaryTreeNode();
e->m_nValue = 6;
e->m_pLeft = nullptr;
e->m_pRight = nullptr;
BinaryTreeNode* f = new BinaryTreeNode();
f->m_nValue = 7;
f->m_pLeft = nullptr;
f->m_pRight = nullptr;
creatTree(root1, a, b);
creatTree(a, c, d);
creatTree(b, e, f);
int expectedSum = 8;
FindPath(root1, expectedSum);
cin.get();
return 0;
}
leetcode437. 路径总和 III
给定一个二叉树,它的每个结点都存放着一个整数值。
找出路径和等于给定数值的路径总数。
路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
此题目中使用了两个递归,
第一个findpath:求出当前节点到叶子节点中所有路径和等于count的路径的数量。
第二个findpath2:遍历所有的节点。
/**
* 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) {
int count = 0;
int cursum = 0;
findPath2(root, sum, cursum, count);
return count;
}
void findPath(TreeNode* root, int sum,int cursum, int& count)
{
if (root == nullptr) //1
{
return;
}
cursum += root->val; //2
/*if (isLeaf(root)) //3
{
cout << sum << endl;
//sum -= root->m_nValue;
}*/
if (sum == cursum)
++count;
findPath(root->left, sum,cursum, count); //4
findPath(root->right, sum,cursum, count); //5
}
void findPath2(TreeNode* root,int sum,int cursum, int& count)
{
if (root == nullptr)
return;
findPath(root, sum, cursum, count);
findPath2(root->left, sum, cursum, count);
findPath2(root->right, sum, cursum, count);
}
};