🏗️ Counting Connected Components in a Graph 🏗️
💡 Intuition:We need to determine how many connected components exist in a graph constructed from the given properties array.Each index in properties represents
# 💡 Intuition:
<!-- Describe your first thoughts on how to solve this problem. -->
We need to determine how many connected components exist in a graph constructed from the given `properties` array.

Each index in `properties` represents a node, and an edge is formed between two nodes if they share at least `k` common distinct integers. The number of connected components in the graph represents our answer.


# 🛠️ Approach:
<!-- Describe your approach to solving the problem. -->
1. Build the Graph:
    - Convert each `properties[i]` list into a set for easy intersection calculations.
    - Create an adjacency list where two nodes are connected if they share at least `k` common numbers.
2. Perform DFS Traversal:
    - Maintain a `visited` list to track explored nodes.
    - Use DFS to traverse all connected nodes, marking them as visited.
    - Each new DFS call represents discovering a new connected component.

# Complexity
- Time complexity:
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
Constructing the adjacency list takes $$O(n^2 * m)$$  in the worst case (checking all pairs).

DFS traversal takes $$O(n + e)$$, where e is the number of edges.

Overall, it remains $$O(n^2 * m)$$ in the worst case.

- Space complexity:
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

$$O(n^2)$$ for adjacency list in the worst case.

$$O(n)$$ for visited array and recursion stack.

Overall: $$O(n^2)$$ worst-case space usage.


# Code
```python3 []
class Solution:
    def numberOfComponents(self, properties: List[List[int]], k: int) -> int:


        n = len(properties)  

        def intersect(a, b):  
            seta = set(a)  
            setb = set(b)  
            return len(seta.intersection(setb))  

        adj = [[] for _ in range(n)]  # Adjacency list to represent the graph  

        # Build the graph  
        for i in range(n):  
            for j in range(i + 1, n):  
                if intersect(properties[i], properties[j]) >= k:  
                    adj[i].append(j)  
                    adj[j].append(i)  # Graph is undirected  

        visited = [False] * n  
        count = 0  

        def dfs(node):  
            visited[node] = True  
            for neighbor in adj[node]:  
                if not visited[neighbor]:  
                    dfs(neighbor)  

        # Count connected components  
        for i in range(n):  
            if not visited[i]:  
                dfs(i)  
                count += 1  

        return count  
```


![DALL·E 2025-03-23 09.58.58 - A fun and engaging poster asking for upvotes on a LeetCode solution. The poster features a graph with connected components highlighted in different co.webp](https://assets.leetcode.com/users/images/f7098d00-272a-4023-8f53-5232fddac2ba_1742704147.0155377.webp)

['Array', 'Depth-First Search', 'Graph', 'Python3']