From 30fc308f52336345112591b5be4bf829b46eb174 Mon Sep 17 00:00:00 2001 From: YDZ Date: Fri, 26 Jul 2019 16:11:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20problem=20547?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../547. Friend Circles.go | 84 +++++++++++++++++++ .../547. Friend Circles_test.go | 52 ++++++++++++ Algorithms/0547. Friend Circles/README.md | 54 ++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 Algorithms/0547. Friend Circles/547. Friend Circles.go create mode 100644 Algorithms/0547. Friend Circles/547. Friend Circles_test.go create mode 100755 Algorithms/0547. Friend Circles/README.md diff --git a/Algorithms/0547. Friend Circles/547. Friend Circles.go b/Algorithms/0547. Friend Circles/547. Friend Circles.go new file mode 100644 index 00000000..cd086be7 --- /dev/null +++ b/Algorithms/0547. Friend Circles/547. Friend Circles.go @@ -0,0 +1,84 @@ +package leetcode + +// 解法一 并查集 + +// UninonSet defind +type UninonSet struct { + roots []int +} + +func (us UninonSet) init() { + for i := range us.roots { + us.roots[i] = i + } +} + +func (us UninonSet) findRoot(i int) int { + root := i + for root != us.roots[root] { + root = us.roots[root] + } + for i != us.roots[i] { + tmp := us.roots[i] + us.roots[i] = root + i = tmp + } + return root +} + +func (us UninonSet) union(p, q int) { + qroot := us.findRoot(q) + proot := us.findRoot(p) + us.roots[proot] = qroot +} + +func findCircleNum(M [][]int) int { + n, count := len(M), 0 + if n == 0 { + return 0 + } + us := UninonSet{} + us.roots = make([]int, n+1) + us.init() + for i := 0; i < n; i++ { + for j := 0; j <= i; j++ { + if M[i][j] == 1 { + x, y := us.findRoot(i), us.findRoot(j) + if x != y { + us.union(x, y) + } + } + } + } + for i := 0; i < n; i++ { + if us.roots[i] == i { + count++ + } + } + return count +} + +// 解法二 FloodFill DFS 暴力解法 +func findCircleNum1(M [][]int) int { + if len(M) == 0 { + return 0 + } + visited := make([]bool, len(M)) + res := 0 + for i := range M { + if !visited[i] { + dfs547(M, i, visited) + res++ + } + } + return res +} + +func dfs547(M [][]int, cur int, visited []bool) { + visited[cur] = true + for j := 0; j < len(M[cur]); j++ { + if !visited[j] && M[cur][j] == 1 { + dfs547(M, j, visited) + } + } +} diff --git a/Algorithms/0547. Friend Circles/547. Friend Circles_test.go b/Algorithms/0547. Friend Circles/547. Friend Circles_test.go new file mode 100644 index 00000000..d481f1a0 --- /dev/null +++ b/Algorithms/0547. Friend Circles/547. Friend Circles_test.go @@ -0,0 +1,52 @@ +package leetcode + +import ( + "fmt" + "testing" +) + +type question547 struct { + para547 + ans547 +} + +// para 是参数 +// one 代表第一个参数 +type para547 struct { + one [][]int +} + +// ans 是答案 +// one 代表第一个答案 +type ans547 struct { + one int +} + +func Test_Problem547(t *testing.T) { + + qs := []question547{ + + question547{ + para547{[][]int{[]int{0, 0, 0}, []int{0, 1, 0}, []int{0, 0, 0}}}, + ans547{3}, + }, + + question547{ + para547{[][]int{[]int{1, 1, 0}, []int{1, 1, 0}, []int{0, 0, 1}}}, + ans547{2}, + }, + + question547{ + para547{[][]int{[]int{1, 1, 0}, []int{1, 1, 1}, []int{0, 1, 1}}}, + ans547{1}, + }, + } + + fmt.Printf("------------------------Leetcode Problem 547------------------------\n") + + for _, q := range qs { + _, p := q.ans547, q.para547 + fmt.Printf("【input】:%v 【output】:%v\n", p, findCircleNum(p.one)) + } + fmt.Printf("\n\n\n") +} diff --git a/Algorithms/0547. Friend Circles/README.md b/Algorithms/0547. Friend Circles/README.md new file mode 100755 index 00000000..92b187a9 --- /dev/null +++ b/Algorithms/0547. Friend Circles/README.md @@ -0,0 +1,54 @@ +# [547. Friend Circles](https://leetcode.com/problems/friend-circles/) + +## 题目: + +There are **N** students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a **direct** friend of B, and B is a **direct**friend of C, then A is an **indirect** friend of C. And we defined a friend circle is a group of students who are direct or indirect friends. + +Given a **N*N** matrix **M** representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are **direct** friends with each other, otherwise not. And you have to output the total number of friend circles among all the students. + +**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. + +**Note:** + +1. N is in range [1,200]. +2. M[i][i] = 1 for all students. +3. If M[i][j] = 1, then M[j][i] = 1. + + +## 题目大意 + +班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。 + +给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果 M[i][j] = 1,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。 + + +注意: + +- N 在[1,200]的范围内。 +- 对于所有学生,有M[i][i] = 1。 +- 如果有 M[i][j] = 1,则有 M[j][i] = 1。 + + +## 解题思路 + + +- 给出一个二维矩阵,矩阵中的行列表示的是两个人之间是否是朋友关系,如果是 1,代表两个人是朋友关系。由于自己和自肯定朋友关系,所以对角线上都是 1,并且矩阵也是关于从左往右下的这条对角线对称。 +- 这题有 2 种解法,第一种解法是并查集,依次扫描矩阵,如果两个人认识,并且 root 并不相等就执行 union 操作。扫完所有矩阵,最后数一下还有几个不同的 root 就是最终答案。第二种解法是 DFS 或者 BFS。利用 FloodFill 的想法去染色,每次染色一次,计数器加一。最终扫完整个矩阵,计数器的结果就是最终结果。