-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathset_mismatch.go
51 lines (43 loc) · 1018 Bytes
/
set_mismatch.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package main
// func findErrorNums(nums []int) []int {
// var ans []int = make([]int, 0)
// for i := 0; i < len(nums); i++ {
// val := math.Abs(nums[i])
// ans[1] ^= (i + 1) ^ int(val)
// if nums[val - 1] < 0 {
// }
// }
// }
func findErrorNums(nums []int) (res []int) {
var a int
for i, n := range nums {
a ^= n // XOR once per number in nums
a ^= i + 1 // XOR once per expected number
}
// find lowest bit, it belongs either to the missing or double value
lowbit := a & -a
b := a
for i, n := range nums {
// filter by low bit
// this will skip either the missing or double value
if n&lowbit > 0 {
b ^= n
}
if (i+1)&lowbit > 0 {
b ^= i + 1
}
}
// XOR a with b to remove b from a
a ^= b
// At this stage, a and b are the double and missing values, but we don't
// know which one is which! Do a final loop to figure out the return order.
for _, n := range nums {
if n == a {
return []int{a, b}
}
if n == b {
return []int{b, a}
}
}
return nil
}