257. Binary Tree Paths
At a Glance
- Topic: trees
- Pattern: Tree DFS + backtracking and DFS / backtracking
- Difficulty: Easy
- Companies: Google, Apple, Meta, Amazon, Bloomberg
- Frequency: Medium
- LeetCode: 257
Problem (one-liner)
Given the root of a binary tree, return all strings representing root-to-leaf paths, formatted as values joined by "->".
Recognition Cues
- Enumerate every root-to-leaf path as a string (or list)
- Backtracking with path buffer, or prefix strings while walking
- Leaf detection: both children absent
Diagram
At-a-glance flow (replace with problem-specific Mermaid as you refine this note). camelCase node IDs; no spaces in IDs.
Loading diagram…
Approaches
- Brute force — build new string at each edge —
O(n²)worst copying. - Optimal — DFS with mutable slice + join at leaves only —
O(n²)worst total characters output,O(h)active storage.
Optimal Solution
Go
package main
import "strconv"
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func binaryTreePaths(root *TreeNode) []string {
if root == nil {
return []string{}
}
result := []string{}
var walk func(*TreeNode, []string)
walk = func(node *TreeNode, prefix []string) {
next := append(prefix, strconv.Itoa(node.Val))
if node.Left == nil && node.Right == nil {
line := next[0]
for index := 1; index < len(next); index++ {
line += "->" + next[index]
}
result = append(result, line)
return
}
if node.Left != nil {
walk(node.Left, next)
}
if node.Right != nil {
walk(node.Right, next)
}
}
walk(root, []string{})
return result
}JavaScript
class TreeNode {
constructor(val = 0, left = null, right = null) {
this.val = val;
this.left = left;
this.right = right;
}
}
function binaryTreePaths(root) {
if (root === null) {
return [];
}
const result = [];
function walk(node, prefixParts) {
const nextParts = prefixParts.concat(String(node.val));
if (node.left === null && node.right === null) {
result.push(nextParts.join('->'));
return;
}
if (node.left !== null) {
walk(node.left, nextParts);
}
if (node.right !== null) {
walk(node.right, nextParts);
}
}
walk(root, []);
return result;
}Walkthrough
Tree 1 / 2,3 / 5 (only 2 has left 5).
| step | prefixParts | leaf? | output |
|---|---|---|---|
at 1 | [1] | no | recurse |
at 2 | [1,2] | no | recurse |
at 5 | [1,2,5] | yes | "1->2->5" |
Invariant: prefixParts always equals values on the path from root to node; only leaves finalize a string.
Edge Cases
- Single-node tree → one string
"val" - Skewed tree → many strings, each length proportional to depth
Pitfalls
- Treating a node with one missing child as a leaf (must have both children nil for leaf in binary tree definition here—actually if one child nil and other non-nil, not a leaf)
- Exponential string concatenation in hot loop—join at leaf keeps work tighter
Similar Problems
- 113. Path Sum II — paths filtered by target sum.
- 437. Path Sum III — path sums without fixed endpoints.
- 102. Binary Tree Level Order Traversal — different organization of nodes, still traversal fluency.
Variants
- Return arrays of ints instead of strings.
- Paths not restricted to leaves (internal endpoints)—adjust base case.
Mind-Map Tags
#trees #backtracking #root-to-leaf #string-build #dfs
Last updated on
Spotted something unclear or wrong on this page?