1. Iterative BFS with Parent Tracking & Visited Count
Intuition
Starting from vertex 0, push (0, -1) into a queue. If any neighbor is already visited and not equal to the parent, a cycle exists. After the queue empties, if the number of visited nodes equals n, the graph is connected and acyclic.
Algorithm
- If edges.length != n - 1, return false.
- Build adjacency list for all n vertices.
- Initialize visited array of size n to false.
- Queue q pushes (0, -1); visited[0] = true.
- Initialize visitedCount = 0.
- While queue is not empty:
- Pop (curr, parent) from q, visitedCount++.
- For each neighbor in adj[curr]:
- If !visited[neighbor]:
- visited[neighbor] = true, q.push((neighbor, curr)).
- Else if neighbor != parent:
- Return false (cycle).
- Return visitedCount == n.
#include <iostream>#include <vector>#include <queue> class Solution {public: bool validTree(int n, std::vector<std::vector<int>>& edges) { if (edges.size() != n - 1) return false; std::vector<std::vector<int>> adj(n); for (const auto& e : edges) { adj[e[0]].push_back(e[1]); adj[e[1]].push_back(e[0]); } std::vector<bool> visited(n, false); std::queue<std::pair<int, int>> q; q.push({0, -1}); visited[0] = true; int visitedCount = 0; while (!q.empty()) { auto [curr, parent] = q.front(); q.pop(); visitedCount++; for (int neighbor : adj[curr]) { if (!visited[neighbor]) { visited[neighbor] = true; q.push({neighbor, curr}); } else if (neighbor != parent) { return false; // Cycle detected } } } return visitedCount == n; }}; int main() { Solution sol; std::vector<std::vector<int>> e1 = {{0,1},{0,2},{0,3},{1,4}}; std::vector<std::vector<int>> e2 = {{0,1},{1,2},{2,3},{1,3},{1,4}}; std::cout << "Tree 1: " << (sol.validTree(5, e1) ? "true" : "false") << " (Expected: true)\n"; std::cout << "Tree 2: " << (sol.validTree(5, e2) ? "true" : "false") << " (Expected: false)\n"; return 0;}Time & Space Complexity
- Time complexity:
O(n) - Space complexity:
O(n)