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出现三次;
当出现三次时,清除此位上的数字;
代码略