由n个元素组成的数组,n-2个数出现了偶数次,两个数出现了奇数次,且这两个数不相等,如何用O(1)的空间复杂度,找出这两个数
思路分析:
方法一:涉及到两个数,就要用到异或定理了:若a^b=x,则a=b^x,b=x^a。对于这道题,假设这两个数分别为a、b,将数组中所有元素异或之后结果为x,因为a!=b,所以x=a^b,且x!=0,判断x中位为1的位数,只需要知道某一个位为1的位数k,如00101100,k可以取2或者3,或者5.因为x中第k位为1表示a或b中有一个数的第k位也为1,假设为a,将x与数组中第k位为1的数进行异或时,也即将x与a以及其他第k位为1的出现过偶数次的数进行异或,化简即为x与a异或,最终结果即为b。
程序示例如下:
#include "stdafx.h"
#include <stdio.h>
void FindElement(int a[], int length)
{
if (a == NULL || length <= )
printf("数组中无元素,找个毛啊。");
else
{
int s = ;
int i;
int k = ;
for (i = ; i < length; i++)
{
s = s^a[i];
}
int s1 = s;
int s2 = s;
while (!(s1 & ))
{
s1 = s1 >> ;
k++;
}
for (i = ; i < length; i++)
{
if ((a[i] >> k) & )
s = s^a[i];
}
printf("%d %d\n", s, s^s2);
}
}
int main()
{
int array[] = { , , , , , , , };
int len = sizeof(array) / sizeof(array[]);
FindElement(array, len);
getchar();
return ;
}
效果如图:

方法二:如果能够把原数组分为两个子数组,在每个子数组中,包含一个只出现一次的数字,而其他数字都出现两次,问题就可以很容易的解决了:分别对两个子数组执行异或运算。
首先从头到尾依次异或数组中的每一个数字,因为其他数字都出现了两次,在疑惑中全部抵消掉了,所以最终得到的结果将是两个只出现一次的数字的异或结果。而这两个数字肯定不一样,那么这个异或结果肯定不为0,也就是说在这个结果数字的二进制表示中至少就有一位为1,否则就为0了。在结果数字中找到第一个为1的位的位置,记为第N位,那么这两个数字一个第N位为1,另一个第N位为0,这样异或后结果数字的第N位才能为1.此时以第N位是不是1为标准把原数组中的数字分为两个子数组,第一个子数组中每个数字的第N位都为1,而第二个子数组的每个数字的第N位都为0.通过这种方法就可以把原数组分成了两个子数组,每个子数组都包含一个只出现一次的数字,而其他数字都出现了两次。
代码如下:
#include "stdafx.h"
#include <stdio.h>
void findOnce(int data[], int n, int &num1, int &num2)
{
if (n < )
return;
int r1 = ;
for (int i = ; i < n; i++)
r1 = r1^data[i];
int bitNum = ;
while (!(r1 & 0x1))
{
r1 = r1 >> ;
bitNum++;
}
int flag = ( << bitNum);
num1 = ;
num2 = ;
for (int j = ; j < n; j++)
{
if (data[j] & flag)
num1 = num1^data[j];
else
num2 = num2^data[j];
}
}
int main()
{
int array[] = { , , , , , , , };
int num1, num2;
findOnce(array, sizeof(array) / sizeof(array[]), num1, num2);
printf("%d\n%d\n", num1, num2);
getchar();
return ;
}
效果如图:

由n个元素组成的数组,n-2个数出现了偶数次,两个数出现了奇数次,且这两个数不相等,如何用O(1)的空间复杂度,找出这两个数的更多相关文章
- 在一个数组中,除了两个数外,其余数都是两两成对出现,找出这两个数,要求时间复杂度O(n),空间复杂度O(1)
题目:在一个数组中,除了两个数外,其余数都是两两成对出现,找出这两个数,要求时间复杂度O(n),空间复杂度O(1) 分析:这道题考察位操作:异或(^),按位与(&),移位操作(>> ...
- 作业帮:给定一个整数数组,找出其中两个数相加等于目标值(去重set)
题目描述 给定一个整数数组,找出其中两个数相加等于目标值 输入 [1,3,5,7,9,11] 10 输出 1,9 3,7 代码: import java.util.HashMap; import ja ...
- LeetCode练习4 找出这两个有序数组的中位数
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 nums2 ...
- 【C语言】给一组组数,仅仅有两个数仅仅出现了一次,其它全部数都是成对出现的,找出这两个数。
//给⼀组组数,仅仅有两个数仅仅出现了一次.其它全部数都是成对出现的,找出这两个数. #include <stdio.h> int find_one_pos(int num) //找一个为 ...
- python经典算法题目:找出这两个有序数组的中位数
题目:找出这两个有序数组的中位数 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以 ...
- 用最小的空间复杂度找出一个长度为n的数组且数据中的元素是[0,n-1]中任一个重复的数据。
用最小的空间复杂度找出一个长度为n的数组且数据中的元素是[0,n-1]中任一个重复的数据. 比如:[1, 2, 3, 3, 2, 2, 6, 7, 8, 9] 中 2 or 3 分析:这道题目,实现比 ...
- 剑指Offer38 数组所有数字出现两次,只有两个出现了一次,找出这两个数字
/************************************************************************* > File Name: 38_Number ...
- 剑指offer40:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
1 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 2 思路和方法 (1)异或:除了有两个数字只出现了一次,其他数字都出现了两次.异或运算中,任 ...
- 260 Single Number III 数组中除了两个数外,其他的数都出现了两次,找出这两个只出现一次的数
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其他所有元素均出现两次. 找出只出现一次的那两个元素.示例:给定 nums = [1, 2, 1, 3, 2, 5], 返回 [3, 5].注 ...
- 给出2n+1个数,其中有2n个数出现过两次,如何用最简便的方法找出里面只出现了一次的那个数(转载)
有2n+1个数,其中有2n个数出现过两次,找出其中只出现一次的数 例如这样一组数3,3,1,2,4,2,5,5,4,其中只有1出现了1次,其他都是出现了2次,如何找出其中的1? 最简便的方法是使用异或 ...
随机推荐
- [Visual Studio] NuGet发布自定义包(Library Package)
源文章:dax.net http://www.cnblogs.com/daxnet/archive/2013/05/07/3064577.html 使用NuGet发布自己的类库包(Library Pa ...
- Hadoop化繁为简(三)—探索Mapreduce简要原理与实践
目录-探索mapreduce 1.Mapreduce的模型简介与特性?Yarn的作用? 2.mapreduce的工作原理是怎样的? 3.配置Yarn与Mapreduce.演示Mapreduce例子程序 ...
- 手把手教你 Mockito 的使用
什么是 Mockito Mockito 是一个强大的用于 Java 开发的模拟测试框架, 通过 Mockito 我们可以创建和配置 Mock 对象, 进而简化有外部依赖的类的测试.使用 Mockito ...
- windows命令行下杀死进程的方法
xp和win7下有两个好东东tasklist和tskill.tasklist能列出所有的进程,和相应的信息.tskill能查杀进程,语法很简单:tskill程序名!或者是tskill 进程id 例如: ...
- Linux及Arm-Linux程序开发笔记(零基础入门篇)
Linux及Arm-Linux程序开发笔记(零基础入门篇) 作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/bee ...
- js,html-点击直接跳转到页面底/顶部
案例一:js控制,无滑动效果 <html> <body> <a href="javascript:void(0);" onclick="ja ...
- 微信nickname乱码(emoji)及mysql编码格式设置(utf8mb4)解决的过程
转:https://segmentfault.com/a/1190000004594385 项目中涉及保存微信的nickname,之前一直正常使用,但是突然遇到一个之前没有遇到的问题.经过调试发现错误 ...
- OAuth 2和JWT - 如何设计安全的API?
OAuth 2和JWT - 如何设计安全的API? Moakap译,原文 OAuth 2 VS JSON Web Tokens: How to secure an API 本文会详细描述两种通用的保证 ...
- C#代码安装Windows服务
using System;using System.Collections.Generic;using System.ServiceProcess;using System.Configuration ...
- N1, T1刷机记录
硬件配置 N1和T1使用的是晶晨Amlogic方案的芯片, 配置明细分别如下, 都是现在盒子的主流配置 N1CPU: Amlogic S905, ARM Cortex-A53 四核 up to 2.0 ...