Python3 solution with detailed explanation
First note: If you hear anything regarding relationship, circle, etc., you should think of a way to interpret it as a graph. \n\nAfter you read the problem stat
First note: If you hear anything regarding relationship, circle, etc., you should think of a way to interpret it as a graph. \n\nAfter you read the problem statement, try to visualize some examples as a graph on a piece of paper. For example, for `M = [[1,1,0],  [1,1,0], [0,0,1]]`. If you draw three nodes `0, 1, 2`, and try to connect them in case `M_{ij}` is one, you would connect node `0` to node `1`, and node `2` would be left alon. How many connected pieces do you have? 2! right? So, there are two friend cycles. That\' the idea behind our solution here. You try to go over all vertices (we have `n` vertices, which is the `len(M`), starting from whatever node you want! Once you start from a vertex, Depth First Search (DFS) algorithm would try to visit every node that can be arrived at given a specific starting vertex. The algorithm only stops if it visits all the vertices in a connected graph. Makes sense? Good! I\'m following the solution of [user8307e](https://leetcode.com/problems/friend-circles/discuss/470456/Python-DFS-solution-with-explanation-beats-97)\n\n\n```\nclass Solution(object):\n    def findCircleNum(self, M):\n        """\n        :type M: List[List[int]]\n        :rtype: int\n        """\n        n = len(M)  #1\n        visited = [False]*n  #2\n        count = 0  #3\n        \n        if not M:  #4\n            return 0  #5\n        \n        def dfs(u):  #6\n            for v in range(n):  #7\n                if M[u][v] == 1 and visited[v] == False:  #8\n                    visited[v] = True  #9\n                    dfs(v)  #10\n        \n        \n        for idx in range(n): #11\n            if visited[idx] == False: #12\n                count += 1 #13\n                visited[idx] == True #14\n                dfs(idx) #15\n        \n        return count #16\n```\n\nThe first three lines are initializations. Note that the line `#2` includes a way of initialization an array without using `numpy` or `graph` or anything else. \n\nLine `#4`: If `M` is empty, then we don\'t have any friend cycle. \n\nLine `#8` and `#9`: It\'s part of the DFS algorithm where it gets a vertex as input (`u`), and checks it versus all other vertices (let\'s call it `v`). If there\'s a connection between `u` and `v`, and this edge has not been visited yet (line `#8`), then it adds `v` to the visited vertices (line `#9`). Finally, it goes one layer deeper (line `#10`), does the exact same thing for `v`. This is the main part of the solution. Note that it doesn\'t necessary need to be recursive but it\'s more convinient this way. \n\n\nThe rest is pretty simple. It\'s the main function. You go over all the nodes, check if it\'s been visited (line `#12`), update the counter (`count`) by one (we update the counter here since if it has not been visited yet, it means that it\'s part of a friend cycle that has not been counted yet). Update the `visited` list so that we know later on that we visited this node. \n\n\nFinally, we return the `count`. Is that clear? \n\n\n===============================================================\nFinal note: Please let me know if you see ant typo/error/ etc. I\'ll try to fix it.\n\nFinal note 2: I find explaining stuff in a simple for instructive for myself, that\'s why I\'m doing this. Thanks for reading.
['Depth-First Search', 'Python', 'Python3']