[260. 只出现一次的数字 III](C语言题解)(位运算)(力扣)

> Problem:

[260. 只出现一次的数字 III](260. 只出现一次的数字 III - 力扣(LeetCode))

# 思路

> 想到数组中只有一个数只出现了一次解法:**所有数异或,最后答案就是那个只出现一次的数**,该题只需将两个不同的数放在不同的分组,再分别进行 只有一个数出现一次  的解法

# 解题方法

> 先将所有数异或,得出的数c的二进制为1的位置就是两个只出现一次的两个数二进制不同的位置

>找出最右边的两个数二进制位不同位置(c的二进制中最右边为1的位置)

>根据该位置等于1和等于0进行分组

>最后两个组所有元素分别异或得到的两个数就是两个只出现一次的数

# 复杂度

时间复杂度:

> O(n)

AC代码:

 int* singleNumber(int* a, int n, int* returnSize) 
 {
     if (n == 2)
     {
         *returnSize = 2;
         return a;
     }
     int c = 0;
     //异或
     for (int i = 0; i < n; i++)
     {
         c ^= a[i];
     }

     //求最右边的1出现在哪一位
     int ret = 0;
     for (int i = 0; i < 32/*一个数最多32位*/; i++)
     {
         if (((c >> i) & 1) == 1)
         {
             //如果c右移i位后最后一位为1,说明第i位为1(两个只出现一次的数这个位置上的数不同),则退出循环,根据第i位的取值分组(两个数会被分到不同的组),
             //分别异或就可分别找出组内只出现一次的数(与整组内只有一个数只出现一次的方法相同)
             ret = i;
             break;
         }
     }
     int* ans = (int*)calloc(2,sizeof(int));
     //分组分别求两组内只出现一次的数(分组规则:第ret位为1的分一组,为0的分一组)
     for (int i = 0; i < n; i++)
     {
         if (((a[i] >> ret) & 1) == 1)
         {
             ans[0] ^= a[i];
         }
         else
         {
             ans[1] ^= a[i];
         }
     }
     *returnSize = 2;
     return ans;
 }

最后祝大家题题AC,天天只想WA~ 

[260. 只出现一次的数字 III](C语言题解)(位运算)(力扣)_第1张图片

你可能感兴趣的:(刷题,算法,数据结构)