【Leetcode】【Medium】Single Number II

Given an array of integers, every element appears three times except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

解题思路:

在 Single Number I 中使用了异或一个数两次,原值不变的性质,即将出现两次的数值当做没出现;同样,如何将出现三次的数字当做没出现,是本题的思路之一。

解题的方法是,将每个整数看做32位,记录每一位上面的位值出现次数;由于只有一个数出现一次,其余数出现3次;因此当一个位上出现3的倍数次时,证明此位不在single number的位序列中,所有出现3的倍数加1次的位,共同组成了single number。

实现方法1:

使用三个int变量,once、twice、thrice分别记录每一位上位值出现的次数;最终once上余留的值,合起来就是只出现一次的数;

 1 class Solution {
 2 public:
 3     int singleNumber(int A[], int n) {
 4         int once = 0, twice = 0, thrice = 0;
 5         for (int i = 0; i < n; i++) {
 6             // 当某位上once和A[i]同时为1时,twice此位设置为1,否则不变
 7             twice |= once & A[i];
 8             // 先不考虑thrice的存在,和twice配合,10为2次,11为3次
 9             once ^= A[i];
10             // 如果once和twice某位均为1,说明已经达到3次,则置thrice为1,否则为0;
11             thrice = once & twice;
12             // 反转thrice再和once与,即当thrice中某位为1时,将once的此位置为0
13             once &= ~thrice;
14             // 反转thrice再和twice与,即当thrice中某位为1时,将twice的此位置为0
15             twice &= ~thrice;
16         }
17         return once;
18     }
19 };

实现方法2:

和方法1类似,用两个int变量合起来表示某位上值出现的次数,即:

00不出现、01出现一次、10出现两次、11出现三次;

当出现三次时,清除此位上的数字;

代码略

原文地址:https://www.cnblogs.com/huxiao-tee/p/4227429.html