数组中只出现一次的数字(三种不同的情况)

136. 只出现一次的数字

136. 只出现一次的数字
在这里插入图片描述

  • 任意两个相同的数字进行异或操作结果为0
  • 任何数与0进行异或操作结果还是原来的数

根据上面这两个定理,由于其他数字都出现了两次,那么这些数字进行异或操作的结果就是0,最后的答案就是出现一次的数字

class Solution {
    public int singleNumber(int[] nums) {
        int ans=0;
        for(int num:nums){
            ans^=num;
        }
        return ans;
    }
}

137. 只出现一次的数字 II

137. 只出现一次的数字 II

在这里插入图片描述

数字是整型,二进制有32位,因此统计出各个bit位上面的1有多少个,个数%3剩下的1的个数就只出现1次的数字的改bit位上的1

class Solution {
    public int singleNumber(int[] nums) {
        int[] cnt=new int[32];
        for(int i=0;i<32;i++){
            for(int num:nums){
                cnt[i]+=((num>>i)&1);
            }
        }
        int ans=0;
        /*
        给出一个bit数组cnt  cnt[0]表示最低位是1还是0 cnt[31]表示最高位是1还是0 
        根据bit位数组还原数字n  
        从最高位开始  每次进行两次操作: 先左移一位 然后和比特位值进行或操作
        */
        for(int i=31;i>=0;i--){
            ans<<=1;
            ans|=cnt[i]%3;
        }
        return ans;
    }
}

260. 只出现一次的数字 III

260. 只出现一次的数字 III
在这里插入图片描述

class Solution {
    public int[] singleNumber(int[] nums) {
        //假设只出现1次的两个数为a,b
        int xor=0;
        for(int num:nums){
            xor^=num;
        }
        //进行异或操作后 xor=a^b
        int mask=xor&(~xor+1);//mask获取xor最右边的1 比如xor右边第2位是1 则xor=0000...10  
        //mask只有一个bit位为1 其他都是0 记作是第k位为1
        //a b的第k位肯定一个是1 一个是0  不妨认为a的第k位是1  b的低k位是0
        //根据第k位是否为0将所有的数字分为两组  设第k为为1的划分到a组
        //a组中的数字肯定是奇数  其余数字都出现两次+数字a
        //因此可以求出a  又因为xor=a^b  所有a^xor=b
        //至此求的a b
        int a=0;
        for(int num:nums){
            if((num&mask)!=0){//num的第k位是1 分到a组
                a^=num;
            }
        }
        return new int[]{a,a^xor};
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 在c语言,如果一个数组只有两个数字出现了一次,可以使用异或的思想。将整个数组的所有数字异或起来,最后的结果就是只出现一次的两个数字的异或结果。然后再找到这个结果的任意一个为1的位,将原数组所有数字按照这个位是否为1分成两组,则每一组必有一个只出现一次的数字。再分别对每一组数字求异或值,就可以得到最终结果了。 ### 回答2: C语言一个数组只有两个数字出现了一次。要找出这两个数字,可以通过遍历整个数组并使用位操作进行处理。 首先,我们需要将数组的所有数字进行异或操作。因为相同的数字异或操作会得到0,所以最终的结果将会是两个只出现一次的数字的异或结果。假设这个结果为result。 接下来,我们需要找到result二进制表示的某一位为1的位。可以通过先将result与(result - 1)相与得到。这样得到的结果将会是result最低位为1的位,其余位都为0。假设这个结果为mask。 然后,我们可以将mask作为分组依据,将原数组数字分为两组。将数组数字与mask进行位与操作,如果结果为0,则说明该数字的第mask位为0,属于一组;如果结果不为0,则说明该数字的第mask位为1,属于另一组。 最后,我们对每一组数字进行异或操作,可以得到这两个只出现一次的数字。 代码示例: ```c void findTwoNumbers(int arr[], int size) { int result = 0; for (int i = 0; i < size; i++) { result ^= arr[i]; } // 获取最低位为1的位 int mask = result & -result; int num1 = 0; int num2 = 0; for (int i = 0; i < size; i++) { if ((arr[i] & mask) == 0) { num1 ^= arr[i]; } else { num2 ^= arr[i]; } } printf("只出现一次的两个数字分别是:%d和%d\n", num1, num2); } ``` 这样,我们就可以通过以上方法,在一个数组只有两个数字出现一次的情况下找出这两个数字。 ### 回答3: C语言,如果一个数组只有两个数字出现了一次,那么其他数字出现了两次。 我们可以通过遍历整个数组,使用异或操作来找到这两个只出现一次的数字。 首先,我们定义一个变量res为0,用于存储两个只出现一次的数字的异或结果。 然后,我们对整个数组进行一次遍历,每次将数组数字与res进行异或操作,结果再赋值给res。 最终,res的值就是两个只出现一次的数字的异或结果。 接下来,我们需要找到res的二进制表示第一个为1的位数。 我们定义一个变量bit为1,用于表示当前遍历到的位数。 然后,我们使用与操作将bit与res进行与操作,判断位数bit是否存在于res的二进制表示。 当结果为0时,表示当前位数bit不存在于res的二进制表示,我们将bit的值左移一位,进入下一个位数的判断。 当结果不为0时,表示当前位数bit存在于res的二进制表示。 此时,我们对数组进行第二次遍历,将数组数字与bit进行与操作。 对于结果为0的数字,我们将其与res进行异或操作,结果赋值给res。 对于结果不为0的数字,我们将其与res进行异或操作,结果再赋值给res。 最终,res的值就是其一个只出现一次的数字。 我们可以再遍历整个数组,使用异或操作将res与数组的每个数字进行异或操作,结果再赋值给res。 最终,res的值就是另一个只出现一次的数字。 以上就是用C语言解决一个数组只有两个数字出现了一次的问题的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodePanda@GPF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值