zoukankan      html  css  js  c++  java
  • 《剑指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;
        }
    };
    牛客网提交代码
  • 相关阅读:
    用于表示socket的结构体
    Parcelable与Serializable接口的用法和区别
    java类初始化顺序
    孙卫琴java面向对象编程学习笔记
    linux档案权限
    js弹出模态与非模态页面
    ubuntu开启默认的root用户
    java开发实战学习笔记1
    JQuery ajax回调函数
    hadoop命令
  • 原文地址:https://www.cnblogs.com/ZSY-blog/p/12604157.html
Copyright © 2011-2022 走看看