剑指Offer算法实现之二十五:二叉树中和为某一值的路径

来源:互联网 发布:重庆市科委人工智能 编辑:程序博客网 时间:2024/04/29 16:01
题目:输入二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从数的根节点开始往下一直到叶节点所经过的节点形成一条路径。二叉树的接待你定义如下:
struct BinaryTreeNode {    int m_nValue;    BinaryTreeNode *m_pLeft;    BinaryTreeNode *m_pRight;};

思路:

递归,函数参数中维护”路径“,回溯。

编译环境:ArchLinux+Clang3.3, C++11

实现一:

#include <iostream>#include <vector>#include <cstring>#include <cctype>using namespace std;struct BinaryTreeNode {    int m_nValue;    BinaryTreeNode *m_pLeft;    BinaryTreeNode *m_pRight;};void do_printPath(BinaryTreeNode *pRoot, vector<int>& path, int expectedSum, int pathSum);/** Wrapper: 打印符合条件的路径 *//void printPath(BinaryTreeNode *pRoot, int expectedSum){    if (pRoot == nullptr) return;    vector<int> path;    do_printPath(pRoot, path, expectedSum, 0);}void do_printPath(BinaryTreeNode *pRoot, vector<int>& path, int expectedSum, int pathSum){    path.push_back(pRoot->m_nValue);    pathSum += pRoot->m_nValue;        bool isLeaf = !pRoot->m_pLeft && !pRoot->m_pRight;    if (isLeaf && pathSum == expectedSum) {        for (auto i : path) {            cout << i << ' ';        }        cout << endl;    }/** 递归 **/    if (pRoot->m_pLeft)         do_printPath(pRoot->m_pLeft, path, expectedSum, pathSum);    if (pRoot->m_pRight)        do_printPath(pRoot->m_pRight, path, expectedSum, pathSum);    path.pop_back(); // 回溯}int getNum(const char *start, const char *end, int *moved){    int n = 0;    while (start < end && isdigit(*start)) {        (*moved)++;        n *= 10;        n += *start - '0';        start++;    }    return n;}/**  * 根据二叉树的字符表示形式(形如"1(2,3(,4))")创建二叉树  * 区间:[start, end)**/BinaryTreeNode *createTree(const char *start, const char *end){    if (start >= end) {        return nullptr;    }//    if (end - start == 1) {//        return new BinaryTreeNode{*start-'0', nullptr, nullptr};//    }    int rootLen = 0;    int rootValue = getNum(start, end, &rootLen);    if (start + rootLen == end) {        return new BinaryTreeNode{rootValue, nullptr, nullptr};    }    const char *start1 = start + rootLen + 1;    const char *end1 = start + rootLen + 1;    int cnt = 0;    while (true) {        if (*end1 == '(') cnt++;        if (*end1 == ')') cnt--;        if (*end1 == ',' && cnt == 0) break;        end1++;    }    const char *start2 = end1+1;    const char *end2 = end1+1;    cnt = 0;    while (true) {        if (*end2 == '(') cnt++;        if (*end2 == ')' && cnt == 0) break;        if (*end2 == ')') cnt--;        end2++;    }    return new BinaryTreeNode{rootValue,                     createTree(start1, end1),                    createTree(start2, end2)};}BinaryTreeNode *createTree(const char *str){    return  createTree(str, str + strlen(str));}/** 打印二叉树 **/void printTree(BinaryTreeNode *pRoot){    if (!pRoot) return;    cout << pRoot->m_nValue;    if (pRoot->m_pLeft || pRoot->m_pRight) cout << '(';    if (pRoot->m_pLeft) {        printTree(pRoot->m_pLeft);    }    if (pRoot->m_pLeft || pRoot->m_pRight) cout << ',';    if (pRoot->m_pRight) {        printTree(pRoot->m_pRight);    }    if (pRoot->m_pLeft || pRoot->m_pRight) cout << ')';}int main(){    BinaryTreeNode *pRoot = createTree("10(5(4,7),12)");    printTree(pRoot); cout << endl;    printPath(pRoot, 22);}