22 * [137] Single Number II
33 *
44 * 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+ *
66 * Note:
7- *
7+ *
88 * Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
9- *
9+ *
1010 * Example 1:
11- *
12- *
11+ *
12+ *
1313 * Input: [2,2,3,2]
1414 * Output: 3
15- *
16- *
15+ *
16+ *
1717 * Example 2:
18- *
19- *
18+ *
19+ *
2020 * Input: [0,1,0,1,0,1,99]
2121 * Output: 99
22- *
22+ *
2323 */
2424pub struct Solution { }
2525
2626// submission codes start here
2727
2828/*
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
3030
31- 第一个链接给出了通用解法: 对于一个数出现 M 次其它数都出现了 K 的场景, 我们可以用位运算记录 K 种状态(作为一个计数器)来解
31+ 第一个链接给出了通用解法: 对于一个数出现 M 次其它数都出现了 K 的场景, 我们可以用位运算记录 K 种状态(作为一个计数器)来解
3232
33- 这题的真值表(3种状态使用2位):
33+ 这题的真值表(3种状态使用2位):
3434
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
3939
40- 根据数电的知识, 要根据这个真值表写出逻辑表达式, 以输出端为 '1' 的结果为准, 将每行的输入变量写成 AND 形式, 其中为 0 的输入量需要取反, 再将这几个 AND 形式做 OR 即可
40+ 根据数电的知识, 要根据这个真值表写出逻辑表达式, 以输出端为 '1' 的结果为准, 将每行的输入变量写成 AND 形式, 其中为 0 的输入量需要取反, 再将这几个 AND 形式做 OR 即可
4141
42- 令 a' = 1, 则:
42+ 令 a' = 1, 则:
4343
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
4747
48- a' = (~a & b & c) | (a & ~b & ~c)
48+ a' = (~a & b & c) | (a & ~b & ~c)
4949
50- 同理:
50+ 同理:
5151
52- b' = (~a & b & ~c) | (~a & ~b & c)
52+ b' = (~a & b & ~c) | (~a & ~b & c)
5353
54- 这个每轮计算的位次数达到 17 次, 可以再优化一下:
54+ 这个每轮计算的位次数达到 17 次, 可以再优化一下:
5555
56- 对 b' 化简: b' = ~a & (b & ~c | ~b & c) = ~a & b ^ c
56+ 对 b' 化简: b' = ~a & (b & ~c | ~b & c) = ~a & b ^ c
5757
58- 但这时 a 仍然比较复杂, 我们可以考虑能否用每轮算出的 b' 来简化 a 的计算, 则:
58+ 但这时 a 仍然比较复杂, 我们可以考虑能否用每轮算出的 b' 来简化 a 的计算, 则:
5959
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
6363
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
6565
66- 这个就和最开始第二链接里给出的超简洁解法一致了
66+ 这个就和最开始第二链接里给出的超简洁解法一致了
6767
68- 最后的话, a 或 b 为 1 都可以输出到 1 (目标数出现1次或出现2次), 输出 a | b 即可
69- */
68+ 最后的话, a 或 b 为 1 都可以输出到 1 (目标数出现1次或出现2次), 输出 a | b 即可
69+ */
7070impl Solution {
7171 pub fn single_number ( nums : Vec < i32 > ) -> i32 {
7272 let ( mut a, mut b) = ( 0 , 0 ) ;
7373 for & num in nums. iter ( ) {
7474 b = !a & ( b ^ num) ;
7575 a = !b & ( a ^ num) ;
7676 }
77- return a | b
77+ return a | b;
7878 }
7979}
8080
@@ -86,6 +86,6 @@ mod tests {
8686
8787 #[ test]
8888 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 ) ;
9090 }
9191}
0 commit comments