如何计算二叉树所有路径上的数字和

Posted on Thu 22 August 2024 in Journal

Abstract 如何计算二叉树所有路径上的数字和
Authors Walter Fan
 Category    learning note  
Status v1.0
Updated 2024-08-22
License CC-BY-NC-ND 4.0

拳不离口, 曲不离手

身为一个专业程序员, 一天不练习算法套路, 一天手就会生, 今天来练练下面这道题目, 忙活了好一会儿才搞定, 手确实有点生.

Question

给定一个二叉树, 求从根节点和叶子节点的所有路径所组成的数字之和

例如如下的二叉树

           1
          / \
         2   3
        / \
       4   5

它的遍历路径为

  • 124
  • 125
  • 13

总和为 262

Solution

废话不多说, 直接贴代码, 其实主要就是二叉树的深度遍历

#include <iostream>
#include <vector>

using namespace std;

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;

    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};

void dfs(TreeNode* node, std::vector<int>& path, std::vector<std::string>& paths) {
    if (!node) return;

    // Add the current node's value to the path
    path.push_back(node->val);

    // If it's a leaf node, convert the path to a string and add to paths vector
    if (!node->left && !node->right) {
        std::string leafPath;
        for (int i = 0; i < path.size(); ++i) {
            //if (i > 0) leafPath += "->";
            leafPath += std::to_string(path[i]);
        }
        paths.push_back(leafPath);
    }

    // Recursively traverse the left and right subtrees
    dfs(node->left, path, paths);
    dfs(node->right, path, paths);

    // Backtrack: remove the current node's value from the path
    path.pop_back();
}

std::vector<std::string> getRootToLeafPaths(TreeNode* root) {
    std::vector<std::string> paths;
    std::vector<int> path;
    dfs(root, path, paths);
    return paths;
}

TreeNode* createTree(const std::vector<int>& values, int index) {
    if (index >= values.size() || values[index] == -1) {
        return nullptr;
    }
    TreeNode* node = new TreeNode(values[index]);
    node->left = createTree(values, 2 * index + 1);
    node->right = createTree(values, 2 * index + 2);
    return node;
}

void deleteTree(TreeNode* node) {
    if (!node) return;
    deleteTree(node->left);
    deleteTree(node->right);
    delete node;
}

int kata12_tree_path_sum(int argc, char** argv) {
    // Example usage:
    // Creating a binary tree with the following structure:
    //       1
    //      / \
    //     2   3
    //    / \
    //   4   5
    std::vector<int> values = {1, 2, 3, 4, 5, -1, -1};
    TreeNode* root = createTree(values, 0);

    // Get all root-to-leaf paths
    std::vector<std::string> paths = getRootToLeafPaths(root);

    int sum = 0;
    for (const auto& path : paths) {
        std::cout << path << std::endl;
        sum += atoi(path.c_str());
    }
    cout << "sum=" << sum << endl;
   // Clean up the tree to prevent memory leaks
    deleteTree(root);

    return 0;
}

本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。