题目原址
https://leetcode.com/problems/friend-circles/description/
题目描述
Example 1:
Input:
[[1,1,0],
[1,1,0],
[0,0,1]]
Output: 2
Explanation:The 0th and 1st students are direct friends, so they are in a friend circle.
The 2nd student himself is in a friend circle. So return 2.
Example 2:
Input:
[[1,1,0],
[1,1,1],
[0,1,1]]
Output: 1
Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends,
so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1.
给定一个二维数组,数组表示朋友之间是否相识,如
A:[[1,1,0],
B: [1,1,1],
C: [0,1,1]]
表示有3个人A、B和C,第一行表示A与B相识,第二行表示B与A和C相识,第三行表示C与B相识。这里规定如果A与B相识,B与C相识,即使A与C没有直接认识,但是通过传递关系也可以看成A和C是相识的。
解题思路
这个一个递归问题,首先注意一点就是二维数组中主对角线元素是自己与自己相识,所以可以不进行递归。
- 首先定义一个表示组号的全局变量,这里的思想是将同一组的元素的值设置为它的组号。如果当前的元素值为1,则说明他没有被分配到任何组中。
- 因为要遍历整个二维数组,因此在
findCircleNum
方法中需要使用双层循环来遍历所有的元素,这个双层循环中的if语句每进来一次,则说明当前元素与之前遍历过的元素不属于同1组中 - 在递归方法中,首先判断当前元素有没有被访问过,如果没有被访问过,当元素值为1,则将其值置为当前的组号中,判断当前元素位置是否是主对角线位置。
AC代码
class Solution {
private int groupNum = 1;
public int findCircleNum(int[][] M) {
if(M == null || M.length == 0)
return 0;
for(int i = 0; i < M.length; i++) {
for(int j = 0; j < M[0].length; j++){
if(M[i][j] == 1){
groupNum++;
dfs(i, M);
}
}
}
return groupNum - 1;
}
private void dfs(int row, int[][] M) {
// TODO Auto-generated method stub
for(int k = 0; k < M[0].length; k++) {
if(M[row][k] == 1) { //没有被访问过
M[row][k] = groupNum;
if(k != row)
dfs(k, M);
}
}
}
}