1. Convert to Undirected Graph + BFS
Intuition
Traverse the tree to construct an undirected adjacency list map where every edge between parent and child is bidirectional. Then run standard BFS from target up to radius k.
When to apply: When treating the problem strictly as a graph problem.
Algorithm
- Step 1: Traverse the tree using DFS to build graph adjacency list: graph[u].push(v) and graph[v].push(u).
- Step 2: Initialize a queue with target and visited set with target.
- Step 3: Run BFS level by level. Increment distance after each level.
- Step 4: When distance == k, return all elements currently in queue.
#include <iostream>#include <vector>#include <string>#include <algorithm>using namespace std; class Solution {public: void buildGraph(TreeNode* node, TreeNode* parent, unordered_map<int, vector<int>>& adj) { if (!node) return; if (parent) { adj[node->val].push_back(parent->val); adj[parent->val].push_back(node->val); } buildGraph(node->left, node, adj); buildGraph(node->right, node, adj); } vector<int> distanceK(TreeNode* root, TreeNode* target, int k) { unordered_map<int, vector<int>> adj; buildGraph(root, nullptr, adj); queue<int> q; unordered_set<int> visited; q.push(target->val); visited.insert(target->val); int dist = 0; while (!q.empty()) { if (dist == k) { vector<int> ans; while (!q.empty()) { ans.push_back(q.front()); q.pop(); } return ans; } int sz = q.size(); for (int i = 0; i < sz; ++i) { int curr = q.front(); q.pop(); for (int nxt : adj[curr]) { if (!visited.count(nxt)) { visited.insert(nxt); q.push(nxt); } } } dist++; } return {}; }}; int main() { // Sample driver execution cout << "Execution completed successfully." << endl; return 0;} Time & Space Complexity
- Time complexity:
O(n)— Building graph takes O(n) and BFS visits at most n nodes. - Space complexity:
O(n)— Adjacency list stores 2*(n-1) edges, taking O(n) memory.