# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def binaryTreePaths(self, root):
def construct_paths(node, path, paths):
if node:
path += str(node.val)
# if leaf node, append path to paths
if not node.left and not node.right:
paths.append(path)
else:
path += '->'
construct_paths(node.left, path, paths)
construct_paths(node.right, path, paths)
paths = []
construct_paths(root, '', paths)
return paths
/**
* Definition for a binary tree node.
* 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) {}
* };
*/
class Solution {
public:
void constructPaths(TreeNode* node, string path, vector<string>& paths) {
if (node) {
path += to_string(node->val);
if (!node->left && !node->right) {
paths.push_back(path);
} else {
path += "->";
constructPaths(node->left, path, paths);
constructPaths(node->right, path, paths);
}
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> paths;
constructPaths(root, "", paths);
return paths;
}
};
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> paths = new ArrayList<>();
constructPaths(root, "", paths);
return paths;
}
private void constructPaths(TreeNode node, String path, List<String> paths) {
if (node != null) {
path += node.val;
if (node.left == null && node.right == null) {
paths.add(path);
} else {
path += "->";
constructPaths(node.left, path, paths);
constructPaths(node.right, path, paths);
}
}
}
}
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {string[]}
*/
var binaryTreePaths = function(root) {
const paths = [];
function constructPaths(node, path) {
if (node) {
path += node.val;
if (!node.left && !node.right) {
paths.push(path);
} else {
path += '->';
constructPaths(node.left, path);
constructPaths(node.right, path);
}
}
}
constructPaths(root, '');
return paths;
};
Given the root
of a binary tree, return all root-to-leaf paths in any order. Each path should be represented as a string with node values separated by "->"
. A leaf is a node with no children.
For example, for the tree:
1 / \ 2 3 \ 5The output should be
["1->2->5", "1->3"]
.
To solve this problem, we need to find all paths from the root of the tree to its leaves. At first, we might think of traversing all possible paths in the tree and collecting those that end at a leaf. This suggests a recursive approach, as we can process each node and recursively build up the path as we move down the tree.
The brute-force idea would be to try every possible path, but since the tree is acyclic and each node is used only once per path, this is just a traversal. The main challenge is to keep track of the path as we go, and to output it in the required string format.
We also need to decide when a path is complete (i.e., when we hit a leaf node), and then add the current path to our result list. The recursive call should build up the path step by step, appending the current node's value.
We use a depth-first search (DFS) traversal to explore all root-to-leaf paths.
"->"
to the path.
This approach is efficient because each node is visited exactly once, and the path string is constructed as we go, so no extra traversal or backtracking is needed.
"->"
as needed.
Let's use the sample tree:
1 / \ 2 3 \ 5
Final output: ["1->2->5", "1->3"]
The binary tree paths problem is elegantly solved using a recursive depth-first search. By building up the path string as we traverse from the root to each leaf, we efficiently collect all valid root-to-leaf paths. The solution is simple, clear, and leverages recursion to naturally explore all possible paths, with time and space complexity linear in the number of nodes.