题目
在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次。
请找出那个只出现一次的数字。
你可以假设满足条件的数字一定存在。
思考题:
如果要求只使用 O(n) 的时间和额外 O(1) 的空间,该怎么做呢?
样例
输入:[1,1,1,2,2,2,3,4,4,4]
输出:3

解法1:数位统计

从高到低枚举每个数位,如果该位为1的次数%3==1,说明只出现一次的数字这一位也是1
时间复杂度O(nlogn),空间复杂度O(1)

  1. class Solution {
  2. public:
  3. int findNumberAppearingOnce(vector<int>& nums) {
  4. int ans = 0;
  5. for (int i = 31; i >= 0; i--) {
  6. int cnt = 0;
  7. for (auto x: nums) {
  8. if (x >> i & 1) {
  9. cnt++;
  10. }
  11. }
  12. if (cnt % 3 == 1)
  13. ans = ans * 2 + 1;
  14. else ans *= 2;
  15. }
  16. return ans;
  17. }
  18. };

解法二:位运算

构建循环周期为3的二元自动机
时间复杂度O(n),空间复杂度O(1)

  1. class Solution {
  2. public:
  3. int findNumberAppearingOnce(vector<int>& nums) {
  4. int one = 0, two = 0;
  5. for (auto x: nums) {
  6. one = (one ^ x) & ~two;
  7. two = (two ^ x) & ~one;
  8. }
  9. return one;
  10. }
  11. };