面试题3(一):找出数组中重复的数字
题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2, 3, 1, 0, 2, 5, 3},那么对应的输出是重复的数字2或者3。(判断存在即可)
#include<iostream>
using namespace std;
// 方法一:利用排序数组,从头扫描数组
bool duplicate(int nums[], int length) {
if(nums == NULL || length<=0) return false;
for(int i=0; i<length; i++) {
if(nums[i]<0 || nums[i]>length-1) {
return false;
}
}
for(int i=0; i<length; i++) {
while(nums[i] != i) {
if(nums[i] == nums[nums[i]]) {
printf("%d", nums[i]);
return true;
}
int temp = nums[i];
nums[i] = nums[temp];
nums[temp] =temp;
}
}
return false;
}
// 方法二:利用哈希表处理
bool duplicate1(int nums[], int length) {
if(nums == NULL || length<=0) return false;
for(int i=0; i<length; i++) {
if(nums[i]<0 || nums[i]>length-1) {
return false;
}
}
int hashTable[length] = {0};
for(int i=0; i<length; i++) {
if(hashTable[nums[i]] == 0) hashTable[nums[i]]++;
else {
printf("%d", nums[i]);
return true;
}
}
return false;
}
int main() {
int a[7] = {2, 3, 1, 0, 2, 5, 3};
if(!duplicate1(a, 7)){
printf("no duplicate number !!!");
}
return 0;
}
题目二:不修改数组找出重复的数字。
在一个长度为n+1的数组里的所有数字都在 1~n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但不能修改输入的数组。例如,如果输入长度为8的数组{2, 3, 5, 4,3, 2, 6, 7}, 那么对应的输出是重复的数字2或者3。
#include<iostream>
using namespace std;
// 方法一:利用哈希表找出重复数字,该方法可以找出所有重复数字
int getDuplication(const int* nums, int length) {
if(nums == NULL || length<=0) return -1;
int hashTable[length] = {0};
for(int i=0; i<length; i++) {
if(nums[i]>length-1 || nums[i]<0) return -1;
else {
if(hashTable[nums[i]] == 0) hashTable[nums[i]]++;
else return nums[i];
}
}
return -1;
}
/**
* 方法二:二分查找的思路,这种算法相当于以时间换空间,该算法不能保证找出所有重复的数字。
*
**/
int countRange(const int* nums, int length, int start, int end) {
if(nums ==NULL) return 0;
int count=0;
for(int i=0; i<length; i++) {
if(nums[i]>=start && nums[i]<=end) count++;
}
return count;
}
int getDuplication1(const int* nums, int length) {
if(nums == NULL || length<=0) return -1;
int start = 1;
int end = length-1;
while(end>=start) {
int middle = ((end-start)>>1) + start;
int count = countRange(nums, length, start, middle);
if(end==start) {
if(count>1) return start;
else break;
}
if(count > (middle-start+1)) end=middle;
else start=middle+1;
}
return -1;
}
int main() {
int a[7] = {2, 3, 1, 0, 2, 5, 3};
printf("%d", getDuplication1(a, 7));
return 0;
}