题目描述:

一个数组里,除了三个数是唯一出现的,其余的数都出现了偶数次,找出这三个数中任意一个。比如数组序列为[1,2,4,5,6,4,2],只有1、5、6这三个数字是唯一出现的,数字2、4均出现了偶数次,只需要输出数字1、5、6中的任意一个就行。

分析:

题目得出的信息:

(1)数组中的元素一定为奇数个;

(2)由于只有三个数字均出现过一次,显然这三个数字不相同,因此,这三个数字对应的二进制也不可能完全相同。

解题思路:

因此可知:必定能找到二进制数中的某一个bit来区分这三个数(这一个bit的取值或者为0,或者为1),当通过这一个bit的值对数组进行分组的时候,这三个数一定是可以被分到两个子数组中去,。此时我们只需要重点关注哪个子数组中分配了这三个数的其中一个,就可以很容易得到这个数字了。当数组被划分成两个子数组时,这一个bit的值为1的数被分到一个子数组subArray1中,这一个bit的值为0的数被分到了另外一个子数组subArray0.

(1)如果subArray1中元素个数为奇数个,那么对subArray1中的所有数字进行异或操作;由于a^a=0,a^0=a,出现两次的数字通过异或操作得到结果为0,然后再与只出现一次的数字执行异或操作,得到的结果只出现一次的数字。

(2)如果subArray0中元素个数为奇数个,那么对subArray0中的所有数字进行异或操作得到的结果就是其中一个只出现一次的数字。

区分三个数字bit位及算法的实现思路:

32位平台为例,一个int类型的数字占用32位空间,从右往左使用每一位对数组进行分组,分组过程中,计算这个bit值为0的数字的异或的结果result0,出现次数count0;这个bit值为1的所有数字异或结果result1,出现次数为count1;

如果count0是奇数且result1 != 0 ,那么说明这三个数的其中一个数被分配到了这一个bit为0的子数组,因此,这个子数组中所有数字异或的值result0一定为出现的数字。(如果result1=0说明这一个bit不能用来区分这三个数字,此时这三个数字都被划分到子数组subArray0中,因此,result1!=0就可以确定这一个bit可以被用来划分这三个数字)

同理,如果count1是奇数且result0!=0,那么result1就是其中一个出现1次的数。

以[6,3,4,5,9,4,3]为例,出现1次的数字为6(110)、5(101)、9(1001),从右往左第一位就可以区分这三个数字,用这个bit位可以把数字区分为两个子数组subArray0=(6,4,4)和subArray1=(3,5,9,3)。subArray1中所有元素异或的值不等于0,说明出现一次的数字一定在subArray1中出现了,而subArray0中的元素个数为奇数个,说明出现一次的数字其中只有一个被分配到subArray0中了,所以subArray0中所有的元素异或的结果就是这个出现1次的数字6,实现算法的python代码如下:

#判断数字n的二进制数从右往左的第i位是否为1
def isOne(n,i):
return (n&(1<<i)) == 1 def findSingle(arr):
size = len(arr)
for i in range(32):
result0 = result1 = count0 = count1 = 0
for j in range(size):
if isOne(arr[j],i):
result1 ^= arr[i]
count1 += 1
else:
result0 ^= arr[j]
count0 += 1
"""
bit值为1的子数组元素个数为奇数时,且出现1次的的数字被分配到bit值为0的子数组,
说明只有一个出现的数字被分配到bit的值为1的子数组中,异或记过就是这个出现一次的数字
"""
if count1 % 2 == 1 and result0 != 0:
return result1
#只有一个出现一次的数字被分配到bit值为0的子数组中
if count0 % 2 == 1 and result1 != 0:
return result0
return -1

算法面试题(python)——如何找出数组中出现一次的数的更多相关文章

  1. 找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数

    找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数 #include<iostream>using namespace s ...

  2. #7 找出数组中第k小的数

    「HW面试题」 [题目] 给定一个整数数组,如何快速地求出该数组中第k小的数.假如数组为[4,0,1,0,2,3],那么第三小的元素是1 [题目分析] 这道题涉及整数列表排序问题,直接使用sort方法 ...

  3. 一起来刷《剑指Offer》-- 题目一:找出数组中重复的数字(Python多种方法实现)

    数组中重复的数字 最近在复习算法和数据结构(基于Python实现),然后看了Python的各种"序列"--比如列表List.元组Tuple和字符串String,后期会写一篇博客介绍 ...

  4. python找出数组中第二大的数

    #!usr/bin/env python #encoding:utf-8 ''''' __Author__:沂水寒城 功能:找出数组中第2大的数字 ''' def find_Second_large_ ...

  5. 找出数组中出现奇数次的元素<异或的应用>

    点击打开链接:百度面试题之找出数组中之出现一次的两个数(异或的巧妙应用) 题目描述|:给定一个包含n个整数的数组a,其中只有一个整数出现奇数次,其他整数都出现偶数次,请找出这个整数 使用异或操作,因为 ...

  6. 《剑指offer》第三_一题(找出数组中重复的数字,可改变数组)

    // 面试题3(一):找出数组中重复的数字 // 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了, // 也不知道每个数字重复了几次.请 ...

  7. [LeetCode] Find All Numbers Disappeared in an Array 找出数组中所有消失的数字

    Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and ot ...

  8. 剑指Offer:找出数组中出现次数超过一半的元素

    题目:找出数组中出现次数超过一半的元素 解法:每次删除数组中两个不同的元素,删除后,要查找的那个元素的个数仍然超过删除后的元素总数的一半 #include <stdio.h> int ha ...

  9. 找出数组中最大值and索引

    找出数组中的最大值和和最大值的索引位置..... 第一中方法: /** * 找出数组中最大值和最大值的索引 * @param args */ public static void main(Strin ...

随机推荐

  1. Blender学习笔记

    本文是根据B站上面,顺子老师的视频学习整理,建模部分,并未设计到渲染,内容整理所得 下载安装,可以直接在blender官网下载,建议下载最新版吧.因为每次软件的更新都会有新的东西出现,在使用中把你的心 ...

  2. 树形插件zTree与组织插件jOrgChart交互

    <html> <head> <title>组织架构</title> <meta http-equiv="content-type&quo ...

  3. 【Git】Git使用记录: 基于git ignore文件将remote上的文件untrack

    话不多说直接上步骤: git bash直接干到你的code. 直接敲命令: git rm -r --cached . rm是remove 命令 -r将允许递归删除 -cached只会从索引中删除文件. ...

  4. 加sogou 和wps

    刚装完系统,装常用工具: sogoupinyin / wps linux ==========sogoupinyin=========================1.sogou linux 下载d ...

  5. Unity外包团队:关于手机unity游戏开发的技术选型

    技术选型 Unity引擎内置了多人联机的解决方案,涵盖了从最底层的网络数据传输,到不同玩家之间的消息发送,再到游戏大厅这样的高级功能.考虑到Unity官方提供的云服务(Internet Service ...

  6. OpenGL.tutorial06键盘和鼠标

    1.这个图是用 Excel画的 简单示意图(单元格边框,视图-->网格线) 1.1.中间的 正立方体 处于 X/Y/Z轴的中心,边长为2 ZC:代码中 原版是 人物在 (0,0,5)处,水平夹角 ...

  7. JDK内置工具使用

  8. 虹软离线人脸识别 ArcFace 2.0 Demo [C++]

    环境: win10(10.0.16299.0)+ VS2017 sdk版本:ArcFace v2.0 OPENCV3.43版本 x64平台Debug.Release配置都已通过编译 下载地址:http ...

  9. Project Euler 345: Matrix Sum

    题目 思路: 将问题转化成最小费用流 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #incl ...

  10. php正则匹配

    在PHP中,有两套正则表达式函数库,两者功能相似,只是执行效率上有所不同, 一套是有"preg_"为前缀命名的函数,一套有"ereg_"命名的函数的函数, 一个 ...