《剑指offer》第三十四题:二叉树中和为某一值的路径

// 面试题34:二叉树中和为某一值的路径
// 题目:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所
// 有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

#include <cstdio>
#include "BinaryTree.h"
#include <vector>

void FindPath(BinaryTreeNode* pRoot, int expectedSum, std::vector<int>& path, int& currentSum);

void FindPath(BinaryTreeNode* pRoot, int expectedSum)
{
    if (pRoot == nullptr || expectedSum <= 0)
        return;

    std::vector<int> path;
    int currentSum = 0;
    FindPath(pRoot, expectedSum, path, currentSum);
}

void FindPath
(
    BinaryTreeNode* pRoot,
    int expectedSum,
    std::vector<int>& path,
    int& currentSum
)
{
    //当前节点加入路径
    path.push_back(pRoot->m_nValue);
    currentSum += pRoot->m_nValue;

    //如果当前节点为叶节点, 且当前和和预期一致, 打印路径
    if (pRoot->m_pLeft == nullptr && pRoot->m_pRight == nullptr
        && currentSum == expectedSum)
    {
        printf("A path is found: ");
        std::vector<int>::iterator iter = path.begin();
        for (; iter != path.end(); ++iter)
            printf("%d	", *iter);
        printf("
");
    }

    //存在左右节点
    if (pRoot->m_pLeft)
        FindPath(pRoot->m_pLeft, expectedSum, path, currentSum);
    if (pRoot->m_pRight)
        FindPath(pRoot->m_pRight, expectedSum, path, currentSum);

    //返回时删除掉此节点
    currentSum -= pRoot->m_nValue;
    path.pop_back();
}
// ====================测试代码====================
void Test(const char* testName, BinaryTreeNode* pRoot, int expectedSum)
{
    if (testName != nullptr)
        printf("%s begins:
", testName);

    FindPath(pRoot, expectedSum);

    printf("
");
}

//            10
//         /      
//        5        12
//       /        
//      4  7     
// 有两条路径上的结点和为22
void Test1()
{
    BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
    BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
    BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
    BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
    BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);

    ConnectTreeNodes(pNode10, pNode5, pNode12);
    ConnectTreeNodes(pNode5, pNode4, pNode7);

    printf("Two paths should be found in Test1.
");
    Test("Test1", pNode10, 22);

    DestroyTree(pNode10);
}

//            10
//         /      
//        5        12
//       /        
//      4  7     
// 没有路径上的结点和为15
void Test2()
{
    BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
    BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
    BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
    BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
    BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);

    ConnectTreeNodes(pNode10, pNode5, pNode12);
    ConnectTreeNodes(pNode5, pNode4, pNode7);

    printf("No paths should be found in Test2.
");
    Test("Test2", pNode10, 15);

    DestroyTree(pNode10);
}

//               5
//              /
//             4
//            /
//           3
//          /
//         2
//        /
//       1
// 有一条路径上面的结点和为15
void Test3()
{
    BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
    BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
    BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
    BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
    BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);

    ConnectTreeNodes(pNode5, pNode4, nullptr);
    ConnectTreeNodes(pNode4, pNode3, nullptr);
    ConnectTreeNodes(pNode3, pNode2, nullptr);
    ConnectTreeNodes(pNode2, pNode1, nullptr);

    printf("One path should be found in Test3.
");
    Test("Test3", pNode5, 15);

    DestroyTree(pNode5);
}

// 1
//  
//   2
//    
//     3
//      
//       4
//        
//         5
// 没有路径上面的结点和为16
void Test4()
{
    BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
    BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
    BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
    BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
    BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);

    ConnectTreeNodes(pNode1, nullptr, pNode2);
    ConnectTreeNodes(pNode2, nullptr, pNode3);
    ConnectTreeNodes(pNode3, nullptr, pNode4);
    ConnectTreeNodes(pNode4, nullptr, pNode5);

    printf("No paths should be found in Test4.
");
    Test("Test4", pNode1, 16);

    DestroyTree(pNode1);
}

// 树中只有1个结点
void Test5()
{
    BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);

    printf("One path should be found in Test5.
");
    Test("Test5", pNode1, 1);

    DestroyTree(pNode1);
}

// 树中没有结点
void Test6()
{
    printf("No paths should be found in Test6.
");
    Test("Test6", nullptr, 0);
}

int main(int argc, char* argv[])
{
    Test1();
    Test2();
    Test3();
    Test4();
    Test5();
    Test6();

    return 0;
}
测试代码

分析:递归思想。

/*
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> > printPath;
        
        if (root == nullptr || expectNumber <= 0)
            return printPath;
        
        vector<int> path;
        int currentSum = 0;
        
        return FindPath(root, path, printPath, expectNumber, currentSum);
    }
    
    vector<vector<int> > FindPath(
        TreeNode* root, vector<int>& path, 
        vector<vector<int> >& printPath, 
        int expectNumber, int currentSum)
    {
        currentSum += root->val;
        path.push_back(root->val);
        if (root->left == nullptr && root->right == nullptr
           && currentSum == expectNumber)
        {
            vector<int> printTemp;
            vector<int>::iterator iter = path.begin();
            for (; iter != path.end(); ++iter)
            {
                printTemp.push_back(*iter);
            }
            printPath.push_back(printTemp);
        }
        if (root->left)
            FindPath(root->left, path, printPath, expectNumber, currentSum);
        if (root->right)
            FindPath(root->right, path, printPath, expectNumber, currentSum);
        
        currentSum -= root->val;
        path.pop_back();
        return printPath;
    }
};
牛客网提交代码
原文地址:https://www.cnblogs.com/ZSY-blog/p/12604157.html