题目描述:

一个数组里,除了三个数是唯一出现的,其余的数都出现了偶数次,找出这三个数中任意一个。比如数组序列为[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. MATLAB 均方根误差MSE、两图像的信噪比SNR、峰值信噪比PSNR、结构相似性SSIM

    今天的作业是求两幅图像的MSE.SNR.PSNR.SSIM.代码如下: clc; close all; X = imread('q1.tif');% 读取图像 Y=imread('q2.tif'); ...

  2. tomcat启动项目时一直在跑,项目没起来

    1. 在整合maven项目时我遇到一个问题,tomcat启动项目总是报超时,后来我把timeout调到180秒,还是启动超时.看了不是timeout时间短的问题. 2.弄了一天也没解决,后来请大神给看 ...

  3. day19

    """ time 用于处理时间相关 1.获取时间 2.不同格式的时间转换 3.sleep函数"""import time# 浮点型的时间戳 ...

  4. Git 帮助

    Git 配置 配置 git config --global user.name "..." git config --global user.email "...&quo ...

  5. Python读写txt文件时的编码问题

    这个问题来自于一个小伙伴,他在处理中文数据时需要先把里面的文本过滤然后分词,因为里面有许多符号,不仅是中文标点符号,还有✳,emoji等奇怪的符号. 正常情况下,中文的str经过encode('utf ...

  6. ios和android 浏览器适配问题总结

    转自 https://blog.csdn.net/wcy7916/article/details/83345705

  7. 实验十一 团队项目设计完善&编码测试

    任务一: 根据OOD详细设计工作要点,修改完善团队项目系统设计说明书和详细设计说明,将完善后内容以<XX团队项目软件设计方案>为名发布在团队博客中,博文中要突出对完善内容的陈述说明,修改部 ...

  8. springboot缓存注解——@CacheEvict

    @CacheEvict:缓存清除 可以通过key指定清除的数据 如果不写默认参数的值 allEntries = true (是否删除该缓存名中所有数据,默认为false) beforeInvocati ...

  9. Web安全测试工具 Burp Suit 使用简介

    参考文档: https://blog.csdn.net/gitchat/article/details/79168613 https://www.cnblogs.com/nieliangcai/p/6 ...

  10. SQL查询【根据生日计算】

    根据生日日期,获取当前年龄.年龄单位. Select Case when DateDiff(Year, BirthDate, GetDate()) > 0 then DateDiff(Year, ...