Skip to content

Commit abc9bd9

Browse files
author
Shuo
authored
Merge pull request #650 from openset/develop
Add: Accounts Merge
2 parents 53cb78e + 84f988d commit abc9bd9

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,45 @@
11
package accounts_merge
2+
3+
import "sort"
4+
5+
func accountsMerge(accounts [][]string) [][]string {
6+
n := len(accounts)
7+
owner := make(map[string]string, n)
8+
parent := make(map[string]string, n*2)
9+
for _, a := range accounts {
10+
for i := 1; i < len(a); i++ {
11+
parent[a[i]] = a[i]
12+
owner[a[i]] = a[0]
13+
}
14+
}
15+
for _, a := range accounts {
16+
r := root(a[1], parent)
17+
for i := 2; i < len(a); i++ {
18+
p := root(a[i], parent)
19+
parent[p] = r
20+
}
21+
}
22+
union := make(map[string][]string, n)
23+
for email, p := range parent {
24+
r := root(p, parent)
25+
union[r] = append(union[r], email)
26+
}
27+
res := make([][]string, 0, len(union))
28+
for p, emails := range union {
29+
t := make([]string, len(emails)+1)
30+
t[0] = owner[p]
31+
if len(emails) > 1 {
32+
sort.Strings(emails)
33+
}
34+
copy(t[1:], emails)
35+
res = append(res, t)
36+
}
37+
return res
38+
}
39+
40+
func root(e string, parent map[string]string) string {
41+
if parent[e] == e {
42+
return e
43+
}
44+
return root(parent[e], parent)
45+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,81 @@
11
package accounts_merge
2+
3+
import (
4+
"reflect"
5+
"sort"
6+
"testing"
7+
)
8+
9+
type caseType struct {
10+
input [][]string
11+
expected [][]string
12+
}
13+
14+
func TestAccountsMerge(t *testing.T) {
15+
tests := [...]caseType{
16+
{
17+
input: [][]string{
18+
19+
{"John", "[email protected]"},
20+
21+
{"Mary", "[email protected]"},
22+
},
23+
expected: [][]string{
24+
25+
{"John", "[email protected]"},
26+
{"Mary", "[email protected]"},
27+
},
28+
},
29+
{
30+
input: [][]string{
31+
32+
33+
34+
35+
36+
},
37+
expected: [][]string{
38+
39+
40+
41+
42+
},
43+
},
44+
{
45+
input: [][]string{
46+
47+
48+
49+
50+
51+
},
52+
expected: [][]string{
53+
54+
},
55+
},
56+
{
57+
input: [][]string{
58+
59+
60+
61+
62+
63+
},
64+
expected: [][]string{
65+
66+
},
67+
},
68+
}
69+
for _, tc := range tests {
70+
output := accountsMerge(tc.input)
71+
sort.Slice(output, func(i, j int) bool {
72+
if output[i][0] == output[i][0] {
73+
return output[i][1] < output[j][1]
74+
}
75+
return output[i][0] < output[i][0]
76+
})
77+
if !reflect.DeepEqual(output, tc.expected) {
78+
t.Fatalf("input: %v, output: %v, expected: %v", tc.input, output, tc.expected)
79+
}
80+
}
81+
}

0 commit comments

Comments
 (0)