某整形数组中除了两个单身整数外, 其余的整数都是成对出现的, 利用C/C++代码求出这两个单身整数。 要求: 时间复杂度o(n), 空间复杂度o(1)------某公司招聘试题
来源:互联网 发布:仿微博 php源码 编辑:程序博客网 时间:2024/05/07 01:59
先看看这个题目:某整形数组中除了两个单身整数外, 其余的整数都是成对出现的, 利用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位上的数是否为1bool 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
--------------------------
异或的思路, 很巧妙, 以后要注意。 好了, 本文先到此为止。
0 0
- 某整形数组中除了两个单身整数外, 其余的整数都是成对出现的, 利用C/C++代码求出这两个单身整数。 要求: 时间复杂度o(n), 空间复杂度o(1)------某公司招聘试题
- 一个数组中,存在两个只出现一次的数字,其余的数字均出现两次。要求在时间复杂度o(n),空间复杂度为o(1)的情况下找出这两个数字
- 如何判断一个整数数组中是否有重复元素?要求时间复杂度O(n),空间复杂度O(1)
- 如何判断一个整数数组中是否有重复元素?要求时间复杂度O(n),空间复杂度O(1)
- 如何判断一个整数数组中是否有重复元素?要求时间复杂度O(n),空间复杂度O(1)
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。 请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n), 空间复杂度是O(1)
- 一个数组,其中除两个数外,其余的数全是成对出现的,用时间复杂度O(n),空间复杂度O(1)求解不成堆出现的两个数
- 将数组排序,数组中所有的负整数出现在正整数前面(时间复杂度为 O(n), 空间复杂度为 O(1)).
- 给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。 要求:空间复杂度O(1),时间复杂度为O(n)。
- 给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。要求:空间复杂度O(1),时间复杂度为O(n)
- 判断一个整数数组中是否有重复数字出现的O(n)时间复杂度算法
- 如何对n个大小都小于100的整数进行排序,要求时间复杂度O(n),空间复杂度O(1)。
- 不用额外空间的整数交换以及时间复杂度为O(n)空间复杂度为O(1)的排序算法
- 求解一个数组里等于给定整数和的两个数的O(n)时间复杂度算法
- 求解一个数组里等于给定整数和的两个数的O(n)时间复杂度算法
- 如何对n个整数数进行排序,要求时间复杂度O(n),空间复杂度O(1)
- 如何快速找出一个数组中只出现一次的两个数,其他元素出现两次?保证时间复杂度O(n),空间复杂度O(1)
- 数组中未出现的最小正整数(时间复杂度O(N),空间复杂度O(1))
- 关于新三板的股份锁定问题
- C语言入门教程5-进制
- ACM ASCII码排序 陷阱排除
- 第三章 第四十五题
- JAVA基础——字符编码
- 某整形数组中除了两个单身整数外, 其余的整数都是成对出现的, 利用C/C++代码求出这两个单身整数。 要求: 时间复杂度o(n), 空间复杂度o(1)------某公司招聘试题
- C语言入门教程6-变量与内存
- XP用户 慎用360最新版 安全卫士使用有感
- POJ 1661 Help Jimmy
- C++ primer 箭头操作符重载心得体会
- leetcode[21]:Merge Two Sorted Lists
- RDIFramework.NET V2.9版本多语言的实现
- HMM 语音识别 理解
- vs2008和vs2010下配置openmesh