由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? 最简便的方法是使用异或 ...
随机推荐
- Cocos Creator 的实现拖尾效果
在游戏中,有时会需要在某个游戏对象上加上移动后的轨迹若隐若现的效果.使得游戏的效果较好,比如游戏大招,刀光,法术,流星划痕之类. Cocos Creator提供了一种内置的拖尾渐隐效果的实现方法:组件 ...
- cocos2d-x入门学习--准备篇
1.Cocos2D最早是一款用Python语言开发的游戏引擎.Cocos2D是一个开源框架,用于构建二维游戏,演示程序和其他图形界面交互应用等. 2.x的包含两个意思:一方面是C++的文件扩展为CXX ...
- wampServer 安装 Redis 扩展
REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redis是一个开源的使用ANSI C语言编写.遵守B ...
- JVM内存管理--GC算法详解
标记/清除算法 首先,我们回想一下上一章提到的根搜索算法,它可以解决我们应该回收哪些对象的问题,但是它显然还不能承担垃圾搜集的重任,因为我们在程序(程序也就是指我们运行在JVM上的JAVA程序)运行期 ...
- (58)Wangdao.com第九天_JavaScript 对象的基本操作
对象的基本操作 创建对象 var 对象名 = new Object(); // new 函数; 称为构造函数,专门用来创建对象的函数 var god = 给对象增加属性 删除对象 ...
- CentOS 6.8 安装 Erlang 及 RabbitMQ Server
安装 Erlang 19.3 # 安装依赖包 yum install -y gcc gcc-c++ unixODBC-devel openssl-devel ncurses-devel # 下载 er ...
- [Asp.net core]bootstrap分页
摘要 一直在用前后端分离,在一个后台管理的页面中,尝试封装了一个辅助类. 类 /// <summary> /// 分页viewmodel /// </summary> /// ...
- SharePoint 特殊用户标识
To get claim for All Authenticated Users in PS you need to use:$claim = New-SPClaimsPrincipal -Encod ...
- 服务 Service 简单案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- android 异常:ScrollView can host only one direct child
android 采用ScrollView布局时出现异常:ScrollView can host only one direct child. 主要是ScrollView内部只能有一个子元素,即不能并列 ...