剑指offer面试题51

来源:互联网 发布:金正恩的发型 知乎 编辑:程序博客网 时间:2024/06/02 05:50

前2种方法很简单,第三种必须要考虑到条件的限制才有可能想到,即数字范围在n-1之内

#include<iostream>#include<string>#include<queue>using namespace std;/******长度为n的数组,里面的数字范围为0-n-1,判断是否有重复的数字***弄个函数,若有重复数字,返回重复数字,若无则返回-1***///方法1:排序后再扫描//时间复杂度nlog(n)+nint duplicate1(int number[],int length){int i;sort(number,number+length);//递增排序for(i=0;i<length-1;i++){if(number[i]==number[i+1])return number[i];}return -1;}//方法2:哈希表//时间复杂度n,空间复杂度n//哈希结构,data为-1时说明还不存在struct num{int data;struct num *next;};#define M 100struct num *hash[M];//插入加查询是否有重复数字int hash_insert(struct num *h,int num){if(h->data==-1){h->data=num;h->next=new struct num;h->next->data=-1;}else{if(h->data==num)return 1;else return hash_insert(h->next,num);}return 0;}#define HASH_KEY 100int duplicate2(int number[],int len){int i,key;for(i=0;i<len;i++){hash[i]=new struct num;hash[i]->data=-1;}for(i=0;i<len;i++){key=number[i]%HASH_KEY;if( hash_insert(hash[key],number[i])  )return number[i];}return -1;}//方法3:利用题目特性,长度为n的数组,数字大小在n-1内//如果没有重复,则排序后相应下标肯定是下标自身//故用交换方式,比如检测第0个,如果数字是5,就与第五个交换//直到把数字0交换到0位置上//如果0位置不是0,是2的话,则下一步肯定再与2交换//这时候就会发现位置2已经是数字2了,那么就存在重复int duplicate3(int number[],int len){int i,key,temp,place;for(i=0;i<len;i++){while(1){if(number[i]==i)break;else{if(number[i]==number[number[i]])return number[i];else{place=number[i];temp=number[i];number[i]=number[place];number[place]=temp;}}}}return -1;}int main(){int number[]={2,3,1,0,2,5,3};int number1[10]={9,8,7,6,5,4,3,2,1,1};    int length=10,dupnum;dupnum=duplicate3(number1,length);if(dupnum==-1)printf("无重复数字!\n");else printf("重复数字为%d\n",dupnum);}


0 0
原创粉丝点击