数组中只出现一次的数

位操作(应该是异或^),目前已知可解决以下问题:

  1. 数组中,一个元素只出现一次(奇数次),其他出现偶数次;
  2. 数组中,两个元素只出现一次(奇数次),其他出现偶数次;

解决方法详见这两篇博客:

http://blog.csdn.net/morewindows/article/details/7354571

http://blog.csdn.net/morewindows/article/details/8214003

这里将要介绍的是这样一个问题:

数组A中,除了某一个数字x之外,其他数字都出现了三次,而x出现了一次。请给出最快的方法找到x。

解决思路:

如果数组中没有x,那么数组中所有的数字都出现了3次,在二进制上,每位上1的个数肯定也能被3整除。如{1, 5, 1, 5, 1, 5}从二进制上看有:

1:0001

5:0101

1:0001

5:0101

1:0001

5:0101

二进制第0位上有6个1,第2位上有3个1.第1位和第3位上都是0个1,每一位上的统计结果都可以被3整除。而再对该数组添加任何一个数,如果这个数在二进制的某位上为1都将导致该位上1的个数不能被3整除。因此通过统计二进制上每位1的个数就可以推断出x在该位置上是0还是1了,这样就能计算出x了。

推广一下,所有其他数字出现N(N>=2)次,而一个数字出现1次都可以用这种解法来推导出这个出现1次的数字。

代码如下:

C++ Code


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 
/** @brief
 * 数组nums中,x出现一次,其他数字都出现了k次
 * 以O(1)的空间复杂度,找出x
 *
 * @param nums[] int -元素数组
 * @param len int -数组长度
 * @param k int -除待求数组外,其他元素出现k次
 * @return int -返回唯一出现一次的元素
 *
 */
int GetUniqueValue(int nums[], int len, int k)
{
    int bits[32];
    memset(bits, 0, sizeof(bits));

/**< 统计数组中所有元素在某一位上1的个数 */
    unsigned int flag = 1;
    for(int i = 0; i < len; ++i)
    {
        for(int j = 0; j < 32; ++j) // bits[31]保存的是符号位
        {
            bits[j] += ((nums[i] & flag) ? 1 : 0);
            flag = flag << 1;
        }
    }

/**< 去除出现k次的数据 */
    for(int i = 0; i < 32; ++i)
    {
        if(bits[i] % k != 0) bits[i] = 1;
    }

/**< 由于负数存储的是补码,这里将其转换为原码 */
    bool isNegative = bits[31];
    if(isNegative)
    {
        int idx = 0;
        while(idx < 31 && bits[idx] != 1) ++idx; // 由低位到高位找到第一个为1的位置
        ++idx; // 从第一个1之后的位置开始变换(不变换符号位)
        while(idx < 31) bits[idx++] ^= 1; // 0与1互换

}

/**< 根据二进制位及符号位计算该元素的值 */
    int ret = 0;
    for(int i = 30; i >= 0; --i)
    {
        ret = ret * 2 + bits[i];
    }
    if(isNegative) ret = -ret;

return ret;
}

时间: 2024-12-29 11:47:10

数组中只出现一次的数的相关文章

【白话经典算法系列之十七】 数组中只出现一次的数 其他三次

本文地址:http://blog.csdn.net/morewindows/article/details/12684497转载请标明出处,谢谢. 欢迎关注微博:http://weibo.com/MoreWindows 首先看看题目要求: 数组A中,除了某一个数字x之外,其他数字都出现了三次,而x出现了一次.请给出最快的方法找到x. 这个题目非常有意思,在本人博客中有<位操作基础篇之位操作全面总结>这篇文章介绍了使用位操作的异或来解决——数组中其他数字出现二次,而x出现一次,找出x.有<

LeetCode&mdash;&mdash;Single Number(找出数组中只出现一次的数)

问题: Given an array of integers, every element appears twice except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?   分析: 数组中的数除了一个只出现了一次之外,其它都出现了两次, 要找出只出

LeetCode&mdash;&mdash;Single Number II(找出数组中只出现一次的数2)

问题: 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?   Single Number I 升级版,一个数组中其它数出现了

找出数组中只出现一次的数

这个题目有三种变形. 第一种,一个数组中所有数都出现了两次,只有一个数出现了一次,求这个数.这个题比较简单,只要知道数字间异或的特性,就可以很容易的得出答案. int find_num_appear_once(int *data, int length){ if(data==NULL || length==0)return; int i=0; int res=0; for(;i<length;i++){ res ^= data[i]; } return res; } 第二种,一个数组中所有的数都

【剑指offer】数组中只出现一次的数

题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 分析: 经典的异或技巧题 两个相同的数字异或的结果为0,一个数和0异或的结果是其本身,假设现在那两个不同的数字是A和B,那么将整个数组的元素依次异或得到的结果ans就是A和B的异或结果 ans的二进制中第k位的1代表A的第k位和B的第k位不同,我们现在按照第k位是否相同将原数组分成两个子数组,那么必定A和B分别分散在两个子数组中,然后将子数组依次异或,得到的结果就是A和B的值! 至于k的取值则

数组中只出现一次的数字 40

? ? 分析问题 ? ? 任何一个数字异或它自己都等于0,通过这个思想遍历数组,用一个result累计异或操作,如果遇到某一个数两次,必定消除了异或操作,换句话说就是如果我们从头依次异或数组中的每一个数字,那么最终的结果应该是那个只出现一次的数字 ? ? 要想说的更明白一点不如举个例子 ? ? 实例 ? ? 比如int[] array={4,5,5};我们声明一个result=0,然后依次用result去异或array中的每一个数,result异或4,结果为0100,接着异或5,结果为0001,

剑指offer-第六章面试中的各项能力(数组中只出现一次的数字)

题目:输入一个数组,该数组中有两个只出现一次的数字,其他的数字都出现两次,输出出只出现一次的数字. 思路:首先,我们可以将这个数组分成两份,一份里面放一个只出现一次的数字.那么我们该怎么分呢?将整个数组中的数字都异或,那么那些等的数字异或后都化为0,因此最后出现的不为0的数字就是两个只出现一次的数字他们两个异或的结果.我们找到该结果中的最右边的一个1,然后根据这个1将数组划分为两份. Java代码: //数组中只出现一次的数. //题目:数组中其他的数都是出现两次,有两个数只出现一次. publ

算法题1 数组中唯一出现1次的数|唯一出现2次的数

题目描述:一个整型数组里除了1个数字之外,其他的数字都出现了两次,请写程序找出这个只出现一次的数字.要求时间复杂度是 O(n),空间复杂度是 O(1),例如输入数组{2, 4, 3, 3, 2, 5 },因为只有 4 这个数字只出现一次,其他数字都出现了两次,所以输出 4 思路分析:本题以及延伸题目,在剑指offer上有详细描述.利用异或的特性,x^y^x=y^x^x=y.对数组所有元素一次进行异或操作,最终得到的值就是那个只出现一次的数字 代码 1 int FindOnceNum(int ar

数组中只出现一次的数字(剑指offer)思维有点巧

数组中只出现一次的数字 参与人数:1144时间限制:1秒空间限制:32768K 通过比例:21.75% 最佳记录:0 ms|0K(来自  牛客563536号) 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 题目链接:http://www.nowcoder.com/practice/e02fdb54d7524710a7d664d082bb7811?rp=2&ru=/ta/coding-interviews&qru=/ta/coding