给定整数数组,除了一个元素之外,每个元素都出现三次。 找到那个只出现一次的数

本文介绍了一种解决LeetCode中寻找唯一出现一次的整数的问题算法。通过位操作来找出在一个整数数组中仅出现一次的数字,其余数字均出现三次。文章提供了两种实现方法,一种使用32位逐位统计,另一种采用更高级的大神算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本题源自LeetCode

-----------------------------------------------------------------------------

int 整型共有32位,用bitnum[32]存储这n个数据每个二进制位上1出现的个数,再%3,如果为1,那说明这一位是要找元素二进制表示中为1 的那一位。


    int singleNumber(int A[], int n) {
        int result=0;
        for(int i=0;i<32;i++){
            int bit=0;
            for(int j=0;j<n;j++){
                bit+=(A[j]>>i)&1;
            }
            result |= (bit%3)<<i;
        }
        return result;
    }

大神算法: 我没看太明白


public int singleNumber(int[] A) {
        int ones = 0;//记录只出现过1次的bits
        int twos = 0;//记录只出现过2次的bits
        int threes;
        for(int i = 0; i < A.length; i++){
            int t = A[i];
            twos |= ones&t;//要在更新ones前面更新twos
            ones ^= t;
            threes = ones&twos;//ones和twos中都为1即出现了3次
            ones &= ~threes;//抹去出现了3次的bits
            twos &= ~threes;
        }
        return ones; 
    }


<think>题目:给定一个非空整数数组,其中除了一个元素只出现一次外,其余每个元素均出现三次。找出那个只出现一次元素。 思路:由于其他元素都出现三次,我们可以考虑用位运算。常规思路是统计每一位上1出现的,然后对3取模,剩下的就是只出现一次在该位上的值。 具体做法: 遍历32位整数中的每一位(0到31),对于每一位: 统计数组中所有元素在该位上1的个。 如果该位上的1的个除以3的余1,则说明只出现一次在该位上是1,否则为0。 将每一位上得到的结果组合起来,就是只出现一次。 另一种思路是使用状态机,但这里我们采用第一种直观的方法。 注意:由于整数可能是负,所以使用32位有符号整数的表示。我们考虑从0到31位,用位运算提取每一位。 代码实现(Python):</think>### 找出只出现一次元素(其余元素均出现三次) 以下是使用位运算的解决方案,时间复杂度为 O(n),空间复杂度为 O(1): ```python def single_number(nums): # 初始化两个变量用于存储位状态 ones = 0 # 记录出现1的位 twos = 0 # 记录出现2的位 for num in nums: # 更新出现两的位:当前位已在ones中且再出现 twos |= ones & num # 更新出现一次的位:使用异或操作 ones ^= num # 当位同时出现在onestwos时,表示出现三次,需要重置 common_bits = ones & twos ones &= ~common_bits twos &= ~common_bits return ones # 测试用例 print(single_number([2, 2, 3, 2])) # 输出: 3 print(single_number([0, 1, 0, 1, 0, 1, 99])) # 输出: 99 ``` **代码解释:** 1. **核心思路**: - 使用两个变量 `ones` `twos` 跟踪每个位的状态: - `ones`:记录出现奇的位(第一次或第三次出现) - `twos`:记录出现偶的位(第二出现) - 当位出现三次时,重置对应位(相当于模3操作) 2. **循环处理每个字**: ```python twos |= ones & num # 更新出现两的位 ones ^= num # 更新出现一次的位 ``` - `ones & num`:找出当前字中已在 `ones` 中设置的位(即第二出现) - `twos |= ...`:将这些位标记为出现两 - `ones ^= num`:使用异或切换出现奇的位 3. **重置出现三次的位**: ```python common_bits = ones & twos # 找出出现三次的位 ones &= ~common_bits # 重置ones中的这些位 twos &= ~common_bits # 重置twos中的这些位 ``` - 当位同时出现在 `ones` `twos` 时,表示已出现三次 - 使用按位取反 `~` 清除这些位 4. **最终结果**: - 循环结束后,`ones` 中存储的就是只出现一次字 - 出现三次字已被完全重置,出现两字存储在 `twos` 中 **算法特性**: - **时间复杂度**:O(n),只需遍历数组一次 - **空间复杂度**:O(1),只使用固定量的额外空间 - **适用性**:可扩展解决"除一个元素出现k外,其余均出现m"的问题
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值