2
2
* [137] Single Number II
3
3
*
4
4
* Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one.
5
- *
5
+ *
6
6
* Note:
7
- *
7
+ *
8
8
* Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
9
- *
9
+ *
10
10
* Example 1:
11
- *
12
- *
11
+ *
12
+ *
13
13
* Input: [2,2,3,2]
14
14
* Output: 3
15
- *
16
- *
15
+ *
16
+ *
17
17
* Example 2:
18
- *
19
- *
18
+ *
19
+ *
20
20
* Input: [0,1,0,1,0,1,99]
21
21
* Output: 99
22
- *
22
+ *
23
23
*/
24
24
pub struct Solution { }
25
25
26
26
// submission codes start here
27
27
28
28
/*
29
- 糅合了一下 https://leetcode.com/problems/single-number-ii/discuss/43296/An-General-Way-to-Handle-All-this-sort-of-questions. 和 https://leetcode.com/problems/single-number-ii/discuss/43294/Challenge-me-thx
29
+ 糅合了一下 https://leetcode.com/problems/single-number-ii/discuss/43296/An-General-Way-to-Handle-All-this-sort-of-questions. 和 https://leetcode.com/problems/single-number-ii/discuss/43294/Challenge-me-thx
30
30
31
- 第一个链接给出了通用解法: 对于一个数出现 M 次其它数都出现了 K 的场景, 我们可以用位运算记录 K 种状态(作为一个计数器)来解
31
+ 第一个链接给出了通用解法: 对于一个数出现 M 次其它数都出现了 K 的场景, 我们可以用位运算记录 K 种状态(作为一个计数器)来解
32
32
33
- 这题的真值表(3种状态使用2位):
33
+ 这题的真值表(3种状态使用2位):
34
34
35
- a b c/c a'b'/a'b'
36
- 0 0 1/0 0 1 /0 0
37
- 0 1 1/0 1 0 /0 1
38
- 1 0 1/0 0 0 /1 0
35
+ a b c/c a'b'/a'b'
36
+ 0 0 1/0 0 1 /0 0
37
+ 0 1 1/0 1 0 /0 1
38
+ 1 0 1/0 0 0 /1 0
39
39
40
- 根据数电的知识, 要根据这个真值表写出逻辑表达式, 以输出端为 '1' 的结果为准, 将每行的输入变量写成 AND 形式, 其中为 0 的输入量需要取反, 再将这几个 AND 形式做 OR 即可
40
+ 根据数电的知识, 要根据这个真值表写出逻辑表达式, 以输出端为 '1' 的结果为准, 将每行的输入变量写成 AND 形式, 其中为 0 的输入量需要取反, 再将这几个 AND 形式做 OR 即可
41
41
42
- 令 a' = 1, 则:
42
+ 令 a' = 1, 则:
43
43
44
- a b c a'
45
- 0 1 1 1 ~a & b & c
46
- 1 0 0 1 a & ~b & ~c
44
+ a b c a'
45
+ 0 1 1 1 ~a & b & c
46
+ 1 0 0 1 a & ~b & ~c
47
47
48
- a' = (~a & b & c) | (a & ~b & ~c)
48
+ a' = (~a & b & c) | (a & ~b & ~c)
49
49
50
- 同理:
50
+ 同理:
51
51
52
- b' = (~a & b & ~c) | (~a & ~b & c)
52
+ b' = (~a & b & ~c) | (~a & ~b & c)
53
53
54
- 这个每轮计算的位次数达到 17 次, 可以再优化一下:
54
+ 这个每轮计算的位次数达到 17 次, 可以再优化一下:
55
55
56
- 对 b' 化简: b' = ~a & (b & ~c | ~b & c) = ~a & b ^ c
56
+ 对 b' 化简: b' = ~a & (b & ~c | ~b & c) = ~a & b ^ c
57
57
58
- 但这时 a 仍然比较复杂, 我们可以考虑能否用每轮算出的 b' 来简化 a 的计算, 则:
58
+ 但这时 a 仍然比较复杂, 我们可以考虑能否用每轮算出的 b' 来简化 a 的计算, 则:
59
59
60
- a (b) b' c a' b'
61
- 1 (0) 0 0 1 0
62
- 0 (1) 0 1 1 0
60
+ a (b) b' c a' b'
61
+ 1 (0) 0 0 1 0
62
+ 0 (1) 0 1 1 0
63
63
64
- 重写一下就是 a' = (a & ~b' & ~c) | (~a & ~b' & c) = ~b' & (a & ~c | ~a & c) = ~b' & a ^ c
64
+ 重写一下就是 a' = (a & ~b' & ~c) | (~a & ~b' & c) = ~b' & (a & ~c | ~a & c) = ~b' & a ^ c
65
65
66
- 这个就和最开始第二链接里给出的超简洁解法一致了
66
+ 这个就和最开始第二链接里给出的超简洁解法一致了
67
67
68
- 最后的话, a 或 b 为 1 都可以输出到 1 (目标数出现1次或出现2次), 输出 a | b 即可
69
- */
68
+ 最后的话, a 或 b 为 1 都可以输出到 1 (目标数出现1次或出现2次), 输出 a | b 即可
69
+ */
70
70
impl Solution {
71
71
pub fn single_number ( nums : Vec < i32 > ) -> i32 {
72
72
let ( mut a, mut b) = ( 0 , 0 ) ;
73
73
for & num in nums. iter ( ) {
74
74
b = !a & ( b ^ num) ;
75
75
a = !b & ( a ^ num) ;
76
76
}
77
- return a | b
77
+ return a | b;
78
78
}
79
79
}
80
80
@@ -86,6 +86,6 @@ mod tests {
86
86
87
87
#[ test]
88
88
fn test_137 ( ) {
89
- assert_eq ! ( Solution :: single_number( vec![ 0 , 0 , 0 , 1 , 1 , 1 , 5 ] ) , 5 ) ;
89
+ assert_eq ! ( Solution :: single_number( vec![ 0 , 0 , 0 , 1 , 1 , 1 , 5 ] ) , 5 ) ;
90
90
}
91
91
}
0 commit comments