【LeetCode】Single Number II

本文介绍了一种算法,用于从一个整数数组中找出那个仅出现一次的数字,其余数字均出现三次。提供了两种解决方案,包括统计每一位上的1再取模的方法,及利用位运算优化内存使用的技巧。

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

参考链接

http://www.cnblogs.com/changchengxiao/p/3413294.html

题目描述

Single Number II

 

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?


题目分析

题目大意:
给出一个数组,除了一个数字,剩下的数字都出现了三次。

思路一:
我们可以对每一个数字的每一个位进行统计再mod3.
如:先统计所有数据中bit0位是1的个数。最后mod3,就得出出现一次的数字的bit0是否为1,因为其他数字如果出现就会出现3次。最后mod3就是0
如:5,5,1,5
0101
0101
0001
0101

每一个bit相加    mod3---------

0001  

int singleNumber(int A[], int n) {
        int i = 0, j = 0, ret = 0,count = 0;
        for(i = 0; i< 32;i++)//32位整数
		{ 
	        for(j = 0;j<n;j++)
	        {
	        	if((A[j]>>i) & 1)count++;		//易错点:不要把&写成&&	        	
			}
			ret |= (count%3)<<i;
			count = 0;							//这里需要清0 
		} 
		return ret;
    }
这样32位数字需要进行32次循环。
这样复杂度就是O(32n)=O(n)

思路二:
int singleNumber(int A[], int n) {
        int one=0, two=0, three=0;			//one记录出现一次,two记录出现两次,three记录出现三次 
        int i = 0; 
		for (i=0;i<n;i++) 
		{
 			two |= one & A[i];				//出现两次的是上一次出现一次,与本次的数字与。然后再或上原来就是两次的。 
			one ^= A[i];					//记录只出现一次的。因为出现两次的就异或为0了,然后记录在两次里了 
 			three = one & two;				//三次就是两次和一次的且 
 			one &= ~three;					//清除出现三次的 
			two &= ~three;
			//printf("%d--%d---%d\n",one,two,three);
 		}
   		return one;

声明三个变量,one,two,three,one记录只出现一次的bit,two记录只出现2次的bit,three记录出现三次的位。

two |= one & A[i];出现两次的等于之前出现一次的与本次即将出现的位取交集。再与原来就是两次的取并集。
类似思路救出三个数字。


代码示例

#include 
   
    

using namespace std;
#if 0
/*
统计每一个bit的个数,再mod3 
*/
class Solution {
public:
    int singleNumber(int A[], int n) {
        int i = 0, j = 0, ret = 0,count = 0;
        for(i = 0; i< 32;i++)//32位整数
		{ 
	        for(j = 0;j
    
     >i) & 1)count++;		//易错点:不要把&写成&&	        	
			}
			ret |= (count%3)<
     
    
   




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值