某整形数组中除了两个单身整数外, 其余的整数都是成对出现的, 利用C/C++代码求出这两个单身整数。 要求: 时间复杂度o(n), 空间复杂度o(1)------某公司招聘试题
先看看这个题目:某整形数组中除了两个单身整数外, 其余的整数都是成对出现的, 利用C代码求出这两个单身整数。 要求: 时间复杂度o(n), 空间复杂度o(1).
我们先用最傻瓜的方式来做吧:
#include <iostream>
using namespace std; // 时间复杂度为o(n^2), 空间复杂度为o(1), 不符合要求
void findSoleNumbers(int a[], int n, int &e1, int &e2)
{
int i = 0;
int j = 0;
int continueFlag = 0; // 控制外层for, 推断是否过滤当前整数
int numberFlag = 0; // 标志第一个、第二个单身整数 for(i = 0; i < n; i++)
{
continueFlag = 0;
for(j = 0; j < n; j++)
{
if(j != i && a[j] == a[i])
{
continueFlag = 1;
break;
}
} if(1 == continueFlag) // 该整数是成双成对的。 过滤掉
{
continue;
} // 可怜的单身整数
if(0 == numberFlag++)
{
e1 = a[i];
}
else
{
e2 = a[i];
}
}
} int main()
{
{
int a[] = {1, 5, 3, 5, 1, 2};
int n = sizeof(a) / sizeof(a[0]);
int e1 = 0;
int e2 = 0; findSoleNumbers(a, n, e1, e2);
cout << e1 << endl;
cout << e2 << endl;
cout << "--------------------------" << endl;
} {
int a[] = {1, 1, 2, 5, 4, 5, 2, 4, 3, 0};
int n = sizeof(a) / sizeof(a[0]);
int e1 = 0;
int e2 = 0; findSoleNumbers(a, n, e1, e2);
cout << e1 << endl;
cout << e2 << endl;
cout << "--------------------------" << endl;
} return 0;
}
结果为:
3
2
--------------------------
3
0
--------------------------
上面程序时间复杂度不满足题目要求。
当然, 有的朋友可能会想到排序, 思路是能够, 可是, 时间复杂度依旧不是o(n), 所以, 排序法我就不介绍了。
因为数组中整数的范围并没有给出。 所以, 也不太适合用计数的方法来做。 那怎么办呢? 假如该题目中的整形数组中仅仅有一个单身整数。 那也好办, 例如以下:
#include <iostream>
using namespace std; // 时间复杂度为o(n), 空间复杂度为o(1), 不符合要求
void findSoleNumber(int a[], int n, int &e)
{
e = 0;
int i = 0;
for(i = 0; i < n; i++)
{
e ^= a[i];
}
} int main()
{
{
int a[] = {1, 5, 3, 5, 1};
int n = sizeof(a) / sizeof(a[0]);
int e = 0; findSoleNumber(a, n, e);
cout << e << endl;
cout << "--------------------------" << endl;
} {
int a[] = {0, 5, 1, 5, 1, 2, 2};
int n = sizeof(a) / sizeof(a[0]);
int e = 0; findSoleNumber(a, n, e);
cout << e << endl;
cout << "--------------------------" << endl;
} return 0;
}
结果:
3
--------------------------
0
--------------------------
上面的方法虽然没有彻底解决这个问题, 但已经提供了思路的雏形了。 以下。 我直接给出可行的方法。 代码本身就是最好的解释, 所以不再解释。 代码例如以下:
#include <iostream>
using namespace std; // 在num的二进制中查找第一个出现1的位置
int findFirstBitEquOne(int num)
{
int bitIndex = 0;
while(bitIndex < 32 && 0 == (num & 1))
{
num >>= 1;
bitIndex++;
} return bitIndex;
} // 推断num二进制的bitIndex位上的数是否为1
bool isBitOne(int num, int bitIndex)
{
return ( (num >>= bitIndex) & 1);
} // 时间复杂度为o(n), 空间复杂度为o(1)
void findSoleNumbers(int a[], int n, int &e1, int &e2)
{
e1 = 0;
e2 = 0; int i = 0;
int result = 0;
for(i = 0; i < n; i++)
{
result ^= a[i]; // 最后的result肯定是两个单身整数的异或值
} int bitIndex = findFirstBitEquOne(result); for(i = 0; i < n; i++)
{
// 对于每个整数, 依据isBitOne原则进行分组, 两个单身整数必定落在不同的组中, 而成双成对的整数必定落在同一组中 if(isBitOne(a[i], bitIndex)) // 组1
{
//cout << "debug1: " << a[i] << endl;
e1 ^= a[i];
}
else // 组2
{
//cout << "debug2: " << a[i] << endl;
e2 ^= a[i];
}
}
} int main()
{
{
int a[] = {1, 5, 3, 5, 1, 2};
int n = sizeof(a) / sizeof(a[0]);
int e1 = 0;
int e2 = 0; findSoleNumbers(a, n, e1, e2);
cout << e1 << endl;
cout << e2 << endl;
cout << "--------------------------" << endl;
} {
int a[] = {1, 1, 2, 5, 4, 5, 2, 4, 3, 0};
int n = sizeof(a) / sizeof(a[0]);
int e1 = 0;
int e2 = 0; findSoleNumbers(a, n, e1, e2);
cout << e1 << endl;
cout << e2 << endl;
cout << "--------------------------" << endl;
} return 0;
}
结果例如以下:
3
2
--------------------------
3
0
--------------------------
异或的思路。 非常巧妙, 以后要注意。 好了。 本文先到此为止。
某整形数组中除了两个单身整数外, 其余的整数都是成对出现的, 利用C/C++代码求出这两个单身整数。 要求: 时间复杂度o(n), 空间复杂度o(1)------某公司招聘试题的更多相关文章
- Class 找出一个整形数组中的元素的最大值
目的:找出一个整形数组中的元素的最大值 以下,我们用类和对象的方法来做. #include<iostream> using namespace std; class Array_m ...
- 算法题:int 数组中 只有一个是id 只出现一次 其他都出现2次 怎么找出只出现一次的id
首先讲一个最笨的算法:时间复杂度为N 空间复杂度为N 代码如下:输出结果id=3完全正确: int[] a = new int[] { 1, 1, 2, 2, 3, 4, 4 }; Dictiona ...
- 34.数组中2个只出现一次的数字[Find two numbers which appear once]
[题目] 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). [分析] 这是一道很新颖的关于位运算的面试题. ...
- 【剑指Offer学习】【面试题40:数组中仅仅出现一次的数字】
题目:一个整型数组里除了两个数字之外.其它的数字都出现了两次,请敲代码找出这两个仅仅出现一次的数字. 要求时间复杂度是O(n),空间复杂度是O(1). 举例说明 比如输入数组{2, 4, 3, 6, ...
- 编程算法 - 数字数组中只出现一次 代码(C)
数字数组中只出现一次 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 一个整型数组里除了两个数字以外, 其它的数字都出现了两次. 请敲代码找出这 ...
- [leetcode]215. Kth Largest Element in an Array 数组中第k大的元素
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- Leetcode26--->Remove Duplicates from Sorted Array(从排序数组中移除相同的元素)
题目: 给定一个排序数组,移除重复出现的元素,保证每个元素最终在数组中只出现一次.返回新数组的长度length; 要求:不能分配额外的一个数组使用,必须使用原地排序的思想,且空间复杂度为O(1) 举例 ...
- 【剑指offer】数组中仅仅出现一次的数字(1)
转载请注明出处:http://blog.csdn.net/ns_code/article/details/27649027 题目描写叙述: 一个整型数组里除了两个数字之外.其它的数字都出现了两次. 请 ...
- 【剑指Offer】40、数组中只出现一次的数字
题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度为O(n),空间复杂度为O(1). 解题思路: 这道题目相对比较难 ...
随机推荐
- Java 大数
How Many Fibs? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- JS学习笔记 - Try / Catch / Finally
<body> <p>请输入 5 和 10 之间的一个数:</p> <input id="demo" type="text&quo ...
- 用py2exe打包成一个exe文件
用py2exe打包成一个exe文件 http://blog.csdn.net/franktan2010/article/details/46514607
- ios 获取手机信息(UIDevice、NSBundle、NSLocale)
iOS的SDK中提供了UIDevice.NSBundle,NSLocale. UIDevice UIDevice提供了多种属性.类函数及状态通知,帮助我们全方位了解设备状况. 从检測电池 ...
- JAVA异常机制简述
1.类的继承结构 在JAVA所有的异常对象都是Throwable类的一个子类的实例 Exception包含两个分支,由于程序错误导致的异常属于RuntimeException,比如数组下标越界,空指针 ...
- 鸟哥的Linux私房菜-----16、程序与资源管理
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...
- JS学习笔记 - fgm练习 - 数字自增 定时器 数字比大小Math.max
<script> window.onload = function(){ var oP = document.getElementsByTagName('p')[0]; var i = 0 ...
- 百度2019校招Web前端工程师笔试卷(9月14日)
8月27日晚,在实习公司加班.当时正在调试页面,偶然打开百度首页console,发现彩蛋,于是投了简历. 9月14日晚,七点-九点,在公司笔试. 笔试题型(有出入): 一.单选20道 1.难度不难,考 ...
- AJAX有关的请求协议及HTTP报文
URI:统一资源标识符 URI=URL+URNURL:统一资源定位符URN:统一资源名称 上边的图片编号对应下边的编号说明: 1.HTTP(占90%市场)/HTTPS/FTP 传输协议(可以理解为快递 ...
- Day2:字符串常用方法
字符串常用方法 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan name = "my \tname is ...