Problem 1:一个数组中有一个数字a只出现一次,其他数字都出现了两次。请找出这个只出现一次的数字?

考察知识点:异或运算

思路:比如数字 b^b = 0

         a^0 = a

因此,可以将数组中的所有数字进行异或,而最终异或的结果即为所求只出现一次的数字a.

代码:

 def SingleNumber1(Array):
ret = 0
for i in Array:
ret ^= i
return ret

==========================================================

Problem 2:一个数组中有一个数字a只出现一次,其他数字都出现了三次。请找出这个只出现一次的数字?

考察知识点:位运算

解法一:

考虑用统计的思路来解这道题,如果一个数出现了三次就消掉,int的32个位都是由0/1组成的,所以将所有数的对应位加起来,

再将各位的统计和对3取模,最终剩下的结果就是要找出的数。

例如:数组 [4 7 4 4](这里为了方便,我们取int的最后四位)

  0  1  0  0

     0  1  1  1

  0  1  0  0

  0  1  0  0

 Sum      0  4  1  1

Sum%3    0  1  1  1

最后Sum%3得到的结果0111即7,就是我们所要求的Single Number

代码:

 def SingleNumber2_1(Array):
ret = 0
for i in range(0,32):
c = 0
d = 1 << i
for j in range(0, len(Array)):
if Array[j] & d:
c += 1
if c % 3:
ret |= d;
return ret

解法二:

考虑每一位的统计值,如果累加到3就归为0,则只会有0/1/2三种情况,所以将大小为32的int数组改为只用两个int即可。

第一个int的第i位为0/1代表第i位当前累加有0/1个 1 ,第二个int的第i位为1代表第i位当前累加有2。

当int1和int2中的第i位均为1时,我们将他们都清零。

例如:数组 [4 7 4 4](这里为了方便,我们取int的最后四位)

4  0  1  0  0

    one     0  1  0  0

two     0      0  0  0

=====================

     0  1  1  1

one     0  0  1  1

two     0      1  0  0

=====================

  0  1  0  0

one     0  0  0  0

two     0      0  1  1

=====================

4  0  1  0  0

  one     0  1  0  0

two     0      0  0  0

=====================

代码:

 def SingleNumber2_2(Array):
one = 0
two = 0
three = 0
for i in range(0, len(Array)):
two |= (one & Array[i])
one ^= Array[i]
three = one & two
two -= three
one -= three
return one

==========================================================

Problem 3:一个数组中有两个数字a、b只出现一次,其他数字都出现了两次。请找出这两个只出现一次的数字?

思路:若将数组中的所以数字进行异或,那么最终结果为 a ^ b

由于a != b,可以知道a ^ b != 0.即结果肯定有一位为1.

根据那一位,我们知道a,b的那一位肯定一个是0,一个是1.

我们找到为1的那一位i,根据i位为0/1将数组分成两组,即可将a, b分开。

因此,我们要解决的是两个Problem 1.

代码:

 def SingleNumber3(Array):
ret = 0
for i in range(0,len(Array)):
ret ^= Array[i]
pos = 0
for j in range(0,32):
if (ret>>j) & 1:
pos = j
break
sub1,sub2 = split(Array,pos)
single1 = SingleNumber1(sub1)
single2 = SingleNumber1(sub2)
return single1,single2 def split(Array, pos):
sub1 = []
sub2 = []
for i in range(0,len(Array)):
if (Array[i]>>pos) & 1:
sub1.append(Array[i])
else:
sub2.append(Array[i])
return sub1,sub2
 def SingleNumber3(Array):
ret = 0
for i in range(0,len(Array)):
ret ^= Array[i]
pos = 0
for j in range(0,32):
if (ret>>i) & 1:
pos = i
break
sub1,sub2 = split(Array,pos)
single1 = SingleNumber1(sub1)
single2 = SingleNumber1(sub2)
return single1,single2 def split(Array, pos):
sub1 = []
sub2 = []
for i in range(0,len(Array)):
if (Array[i]>>pos) & 1:
sub1.append(Array[i])
else:
sub2.append(Array[i])
return sub1,sub2

==========================================================

Problem 4:一个数组中有一个数字a只出现一次,其他数字都出现了K次。请找出这个只出现一次的数字?

考察知识点:位运算 and 分情况解决

① K % 2 == 0

基本思路类似于Problem 1

② K % 2 == 1

基本思路类似于Problem 2

代码:

 def SingleNumber4(Array, k):
if k % 2 == 0:
ret = SingleNumber1(Array)
else:
ret = SingleNumber2_1(Array)
return ret

==========================================================

Problem 5:一个数组中有三个数字a、b、c只出现一次,其他数字都出现了两次。请找出这三个只出现一次的数字?

思路:此处转载自:http://zhedahht.blog.163.com/blog/static/25411174201283084246412/

如果我们把数组中所有数字都异或,那最终的结果(记为x)就是a、b、c三个数字的异或结果(x=a^b^c)。其他出现了两次的数字在异或运算中相互抵消了。

我们可以证明异或的结果x不可能是a、b、c三个互不相同的数字中的任何一个。

我们用反证法证明。假设x等于a、b、c中的某一个。比如x等于a,也就是a=a^b^c。因此b^c等于0,即b等于c。这与a、b、c是三个互不相同的三个数相矛盾。

由于x与a、b、c都各不相同,因此x^a、x^b、x^c都不等于0。

我们定义一个函数f(n),它的结果是保留数字n的二进制表示中的最后一位1,而把其他所有位都变成0。比如十进制6表示成二进制是0110,

因此f(6)的结果为2(二进制为0010)。f(x^a)、f(x^b)、f(x^c)的结果均不等于0。

接着我们考虑f(x^a)^f(x^b)^f(x^c)的结果。由于对于非0的n,f(n)的结果的二进制表示中只有一个数位是1,因此f(x^a)^f(x^b)^f(x^c)的结果肯定不为0。

于是f(x^a)^f(x^b)^f(x^c)的结果的二进制中至少有一位是1。假设最后一位是1的位是第m位。那么x^a、x^b、x^c的结果中,有一个或者三个数字的第m位是1。

我们使用反正法证明不可能三个数字第m位都是1.

如果x^a、x^b、x^c的第m位都是1,那么a、b、c三个数字的第m位和x的第m位都相反,因此a、b、c三个数字的第m位相同。如果a、b、c三个数字的第m位都

是0,x=a^b^c结果的第m位是0。由于x和a两个数字的第m位都是0,x^a结果的第m位应该是0。同理可以证明x^b、x^c第m位都是0。这与我们的假设矛盾。

如果a、b、c三个数字的第m位都是1,x=a^b^c结果的第m位是1。由于x和a两个数字的第m位都是1,x^a结果的第m位应该是0。

同理可以证明x^b、x^c第m位都是0。这还是与我们的假设矛盾。

因此x^a、x^b、x^c三个数字中,只有一个数字的第m位是1。于是我们找到了能够区分a、b、c三个数字的标准。

=============================================================

这里我们需要注意上面只是在已知a,b,c的情况下的理论证明,具体编程则有些不一样:

我们先求得 x = a ^ b ^ c

我们可以将x分别与数组中的元素再进行一次异或,得到一个新的数组,但是并没有改变数组的特性。

比如与数组中有两个相等的数字d

那么经过处理之后这两个数还是相等的,只不过结果为x ^ d

==============================================================

这样我们可以将数组分成两部分,这里假设a的m位为1。

则两个子数组分别为:sub1:包含a   == Problem 1

sub2:包含b, c  == Problem2

代码:

 def SingleNumber5(Array):
x = 0
for i in range(0,len(Array)):
x ^= Array[i]
newArray = []
for j in range(0,len(Array)):
newArray.append(x^Array[j])
lastOneArrary = func(newArray)
ret = 0
for i in range(0,len(lastOneArrary)):
ret ^= lastOneArrary[i]
pos = 0
for j in range(0,32):
if (ret>>j) & 1:
pos = j
break
sub1, sub2 = split(Array,pos)
print(sub1)
print(sub2)
if len(sub1)%2:
single1 = SingleNumber1(sub1)
single2, single3 = SingleNumber3(sub2)
else:
single1 = SingleNumber1(sub2)
single2, single3 = SingleNumber3(sub1)
return single1, single2, single3 def func(Array):
newArray = []
for i in range(0,len(Array)):
pos = 0
for j in range(0,32):
if (Array[i]>>j) & 1:
pos = j
break
newArray.append(1<<pos)
return newArray

LeetCode之Single Number以及拓展的更多相关文章

  1. Leetcode 137 Single Number II 仅出现一次的数字

    原题地址https://leetcode.com/problems/single-number-ii/ 题目描述Given an array of integers, every element ap ...

  2. leetcode 136 Single Number, 260 Single Number III

    leetcode 136. Single Number Given an array of integers, every element appears twice except for one. ...

  3. LeetCode 260. Single Number III(只出现一次的数字 III)

    LeetCode 260. Single Number III(只出现一次的数字 III)

  4. LeetCode 137. Single Number II(只出现一次的数字 II)

    LeetCode 137. Single Number II(只出现一次的数字 II)

  5. LeetCode 136. Single Number(只出现一次的数字)

    LeetCode 136. Single Number(只出现一次的数字)

  6. LeetCode 137 Single Number II(仅仅出现一次的数字 II)(*)

    翻译 给定一个整型数组,除了某个元素外其余的均出现了三次. 找出这个元素. 备注: 你的算法应该是线性时间复杂度. 你能够不用额外的空间来实现它吗? 原文 Given an array of inte ...

  7. LeetCode 136 Single Number(仅仅出现一次的数字)

    翻译 给定一个整型数组,除了某个元素外其余元素均出现两次. 找出这个仅仅出现一次的元素. 备注: 你的算法应该是一个线性时间复杂度. 你能够不用额外空间来实现它吗? 原文 Given an array ...

  8. [LeetCode] 136. Single Number 单独数

    Given a non-empty array of integers, every element appears twice except for one. Find that single on ...

  9. [LeetCode] 137. Single Number II 单独数 II

    Given a non-empty array of integers, every element appears three times except for one, which appears ...

随机推荐

  1. iOS XMPP(2)自己创建客户端

    一.目的以及效果: 用Xcode利用xmpp框架建立客户端,实现向服务器注册添加用户 密码,以及登陆,离线状态 工程的主要结构:新建singleview工程,用xib拖放两个输入框和两个按钮, 并在v ...

  2. python(6)-logging 日志模块

    logging的日志分为5个级别分别为debug(), info(), warning(), error(), critical() 先来看一下简单的代码: logging.basicConfig(f ...

  3. MAC下查看端口占用并杀死进程

    Eclipse在Run on Server时,Tomcat是开启的,但是报错,显示8080.8005和8009端口被占用 终端输入 查看所有开启的端口 sudo lsof -i -P | grep - ...

  4. Eclipse+Axis使用WSDL文件生成Web Service服务端/客户端

    JDK版本:1.5.0_22 Eclipse版本:Helios Service Release 2(3.6.2) WSDL文件的创建过程见http://blog.csdn.net/a19881029/ ...

  5. oracle 学习笔记 复制表结构

    1.复制表结构以及数据 create table d_table_name as select * from s_table_name;  ---注意并不会创建索引 2.只复制表结构 create t ...

  6. poj 1523 求割点

    思路:对于所有节点,每次找的子树,key[root]++;输出时,对于根节点就输出key[root],对于其它节点i,输出key[i]+1; #include<iostream> #inc ...

  7. 设计模式——java

    设计模式:一个程序员对设计模式的理解:“不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开一把 ...

  8. 【转】十二个移动App云测试服务盘点

    随着移动设备.操作系统版本的碎片化,测试工作对于移动开发团队而言越来越成为一个沉重的包袱,不过这也带来了商机,现在市场上有不少服务和平台提供云测试工具,可以对移动App进行自动化测试,提供测试报告和优 ...

  9. HDOJ2015偶数求和

    偶数求和 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  10. Agile.Net 组件式开发平台 - 权限管理组件

    RBAC原则       (1)最小权限原则之所以被RBAC所支持,是因为RBAC可以将其角色配置成其完成任务所需要的最小的权限集.       (2)责任分离原则可以通过调用相互独立互斥的角色来共同 ...