某整形数组中除了两个单身整数外, 其余的整数都是成对出现的, 利用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). 解题思路: 这道题目相对比较难 ...
随机推荐
- PatentTips - Method to manage memory in a platform with virtual machines
BACKGROUND INFORMATION Various mechanisms exist for managing memory in a virtual machine environment ...
- 用py2exe打包成一个exe文件
用py2exe打包成一个exe文件 http://blog.csdn.net/franktan2010/article/details/46514607
- progerssbar-style 属性分析
先看如下代码 <ProgressBar android:id="@+id/stateProgressBar" android:orientation="horizo ...
- ADO.net简单增删改查
嘿嘿,又到了总结了的时间,今天我们学习了ADO.net,什么是ADO.NET:ADO.NET就是一组类库,这组类库可以让我们通过程序的方式访问数据库,就像System.IO下的类操作文件一样, Sys ...
- 转载的:Python os 和 os.path模块详解
os.getcwd()获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录:相当于shell下cd os.curdi ...
- Lucene 查询方式
QueryParser类 QueryParser类对输入字符串的解析 格 式 含 义 “David” 在默认的字段中检索“David”关键字 “content:David” 在“conte ...
- 关于jsonp跨域的问题以及解决方法(跨域、同源与非同源)
什么是跨域? 想要了解跨域,首先需要了解下浏览器的同源机制: JSONP和AJAX相同,都是客户端向服务器端发送请求:给服务器端传递数据 或者 从服务器端获取数据 的方式 JSONP属于非同源策略(跨 ...
- 为SSO 5.5恢复忘记的administrator@vsphere.local密码
转自:http://blog.itpub.net/27042095/viewspace-1179938/ 1. cd \Program Files\VMware\Infrastructure\VMwa ...
- CentOS 7 virt-manager 无法连接本地的hypervisor
OS : CentOS 7 Gnome Desktop 问题描写叙述: CentOS 7 下使用yum install virt-manager之后.使用virt-manager无法连接本地的hype ...
- POJ 3100 Root of the Problem || 1004 Financial Management 洪水!!!
水两发去建模,晚饭吃跟没吃似的,吃完没感觉啊. ---------------------------分割线"水过....."--------------------------- ...