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. cocos2d-x中使用sqlite

    在单机游戏中有几十个场景道具,每一个都有各自的状态(获得.未获得.获得个数)等等,如果在游戏中平凡涉及到这些道具的实时存储,那么使用文本就会稍慢.可以使用sqlite数据库来完成. 下载地址:http ...

  2. hello world of hibernate Annotation

    1:建立所需要的类,如: package com.hibernate.model; import javax.persistence.Entity; import javax.persistence. ...

  3. CentOS(四)--Linux系统的启动级别

    对于绝大多数Linux程序员来说,进入Linux系统后一般看到的是黑乎乎的界面(开发模式),因为系统如果启动选择开发模式,会减少启动时间,优化内存等.但是通常我们刚安装完Linux系统,然后进去以后是 ...

  4. 给jdk写注释系列之jdk1.6容器(7)-TreeMap源码解析

    TreeMap是基于红黑树结构实现的一种Map,要分析TreeMap的实现首先就要对红黑树有所了解.      要了解什么是红黑树,就要了解它的存在主要是为了解决什么问题,对比其他数据结构比如数组,链 ...

  5. web前端常用小函数汇总

    //去掉html标签 function delHtmlTag(str) { var title = str.replace(/<[^>]+>/g, "");// ...

  6. Git CMD - add: Record changes to the repository

    命令格式 git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend] [--dry-run] [(-c ...

  7. 让无线网卡同时工作在 AP 和 STA 模式

    这个帖子里的方法有点过时了,不推荐继续使用. 有的时候会碰到这么一种情况,带着电脑和手机出去蹭网,无奈只有一个账号,手机上了电脑就没得用了,电脑用了手机就上不了网.如果能用电脑连接 Wifi 然后再开 ...

  8. 【Cocos2d入门教程二】Cocos2d-x基础篇

    上一章已经学习了环境的搭建.这一章对基础概念进行掌握.内容大概有: 1.导演 2.场景 3.节点 4.层 4.精灵 1.导演(Director) 导演存在的主要作用: a.环境设定(帧率 初始化ope ...

  9. SQL创建函数及应用

    用户自定义函数在SQL Server中,用户不仅可以使用标准的内置函数,也可以使用自己定义的函数来实现一些特殊的功能.用户自定义函数可以在企业管理器中创建,也可以使用CREATE FUNCTION 语 ...

  10. ios Swift 之github

    1. 软件类 a) 作者集合 http://nondot.org/sabre/ b) swift for facebook SWIFT是一个易于使用的,基于注解的Java来创建勤俭节约序列化类型和服务 ...