数组8:数组中重复的数字
2017-04-30 11:09
148 查看
题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。
思路:要对数组查找重复的数字是一个比较常见的问题。注意,这里只要随便找出一个重复发的数字即可,不用找出全部重复数字;而且这里有一个条件,就是数组中的所有数字都在0到n-1的范围之内。要根据这个特性寻找解决方法。
方法一:通用方法,将数组进行排序O(nlogn),然后遍历数组,计算每个数字出现的次数即可找出所有重复的数字以及确定重复的次数,即转化为一个排序的问题。
方法二:使用散列hash表,理解,hash表的本质就是一个数组,数组有下标和值这两个属性。对于需要分配的数据,需要根据一个散列函数,将数据散列到不同的数组位置上面去,数据必须有一个key和value,根据他的key的hashcode或者其他数值去散列数组中找对应下标的位置,即数据的key的hashcode对应的是散列数组中的下标;散列有一个问题就是当多个数据根据散列函数分配到同一个数组下标位置时,会造成覆盖,于是使用分离链接法在数组每个元素中又创建了一个链表,相同的元素放在这个链表上面。本题中由于只需要记录一下数据在hash表中的出现次数不需要存放具体的数据对象,因此不需要使用链表,直接使用一个数组就可以。即创建一个数组b[],遍历a[]的每个元素时,根据a[i]的值去b[]中下标j=a[i]的位置查找b[a[i]]是否为0,0表示不存在,设为1,1表示已经出现过一次,再次出现就表示重复了。即时间复杂度为O(n),空间复杂度为O(n)
方法三:使用一种巧妙的方法,已知大小为n的数组中的元素值都在0~n-1之间,如果元素没有重复那么排序后位置i与元素值之间应该一一对应,即调整顺序后a[0]=0;a[1]=1;a[2]=2;
a[3]=3……因此当我们遍历数组并按照a[i]==i的准则判断调整数组,每次调整可以使得一个元素到达正确位置,于是最多调整n次就可以使得全部元素到达正确的位置,如果存在重复的数字,那么在调整的过程中间必然会出现a[i]的值与要调整到的位置的值a[a[i]]重复的情况,即发生了重复。时间复杂度O(n),空间复杂度O(1)
//理解:由于数组是引用传递,因此调用duplicate方法时传入一个数组duplication,在方法中对他进行赋值后他原来的数组对象就会相应改变
思路:要对数组查找重复的数字是一个比较常见的问题。注意,这里只要随便找出一个重复发的数字即可,不用找出全部重复数字;而且这里有一个条件,就是数组中的所有数字都在0到n-1的范围之内。要根据这个特性寻找解决方法。
方法一:通用方法,将数组进行排序O(nlogn),然后遍历数组,计算每个数字出现的次数即可找出所有重复的数字以及确定重复的次数,即转化为一个排序的问题。
方法二:使用散列hash表,理解,hash表的本质就是一个数组,数组有下标和值这两个属性。对于需要分配的数据,需要根据一个散列函数,将数据散列到不同的数组位置上面去,数据必须有一个key和value,根据他的key的hashcode或者其他数值去散列数组中找对应下标的位置,即数据的key的hashcode对应的是散列数组中的下标;散列有一个问题就是当多个数据根据散列函数分配到同一个数组下标位置时,会造成覆盖,于是使用分离链接法在数组每个元素中又创建了一个链表,相同的元素放在这个链表上面。本题中由于只需要记录一下数据在hash表中的出现次数不需要存放具体的数据对象,因此不需要使用链表,直接使用一个数组就可以。即创建一个数组b[],遍历a[]的每个元素时,根据a[i]的值去b[]中下标j=a[i]的位置查找b[a[i]]是否为0,0表示不存在,设为1,1表示已经出现过一次,再次出现就表示重复了。即时间复杂度为O(n),空间复杂度为O(n)
方法三:使用一种巧妙的方法,已知大小为n的数组中的元素值都在0~n-1之间,如果元素没有重复那么排序后位置i与元素值之间应该一一对应,即调整顺序后a[0]=0;a[1]=1;a[2]=2;
a[3]=3……因此当我们遍历数组并按照a[i]==i的准则判断调整数组,每次调整可以使得一个元素到达正确位置,于是最多调整n次就可以使得全部元素到达正确的位置,如果存在重复的数字,那么在调整的过程中间必然会出现a[i]的值与要调整到的位置的值a[a[i]]重复的情况,即发生了重复。时间复杂度O(n),空间复杂度O(1)
//理解:由于数组是引用传递,因此调用duplicate方法时传入一个数组duplication,在方法中对他进行赋值后他原来的数组对象就会相应改变
public boolean duplicate(int numbers[],int length,int [] duplication) { //特殊的输入: 空输入是测试案例会检测的,必须解决 if(numbers==null||numbers.length<=0) return false; /*要判断条件不满足的情况:长度不匹配:这个判断剑指offer上面有,最好有,看测试平台的理解 if(numbers.length!=length) return false; //数组值不在0~n-1的范围之内 for(int i=0;i<numbers.length;i++){ if(numbers[i]<0||numbers[i]>numbers.length-1) return false; } */ //遍历数组,不断调整数组到a[i]==i的状态 for(int i=0;i<numbers.length;i++){ while(numbers[i]!=i){ //位置不合理时,需要调整到目标位置,先判断与目标位置的值是否相同重复 if(numbers[i]==numbers[numbers[i]]){ duplication[0]=numbers[i]; return true; }else{ //与目标位置不重复,交换位置 int temp=numbers[numbers[i]]; numbers[numbers[i]]=numbers[i]; numbers[i]=temp; } } } //循环结束还没有重复,说明没有重复 return false; } }
相关文章推荐
- 【我解C语言面试题系列】009 特殊的去除数组中重复数字问题
- 数组a[N],存放了1至N-1个数,其中某个数重复一次。写一个函数,找出被重复的数字.时间复杂度必须为o(N)函数原型:
- 厦门1165 第K小数 树状数组 不重复数字
- 判断一个整数数组中是否有重复数字出现的O(n)时间复杂度算法
- javascript数字数组去重复项
- 【我解C语言面试题系列】008 去除数组中重复数字问题
- java 一个int数组 长度为100 随机生成100个数 即1-100 将其插入进数组 插入的数字不能重复
- ASP 无重复数字随机函数, 数组实现, 并应用于随机显示记录集 By shawl.qiu
- 删除数组中重复的数字
- 有一个数组,存储的元素为1到10000000的任意数,在其中查找出一个重复的数字
- 数组a[N],存放了1至N-1个数,其中某个数重复一次。写一个函数,找出被重复的数字.时间复杂度必须为o(N)函数原型:
- JAVA去掉一个已排序数组的重复数字
- 去除数组中的重复数字
- 判断数组中是否包含重复数字
- 特殊的去除数组中重复数字问题
- 【我解C语言面试题系列】009 特殊的去除数组中重复数字问题
- 去除数组中的重复数字
- 软件开发者面试百问-----有一个数组,里面是从1到1,000,000的整数,其中有一个数字出现了两次,你怎么找出那个重复的数字?
- 有个数组中有100w个数,其中有一个数重复了50w次,要求找出这个数字
- 可用的ASP无重复数字随机函数, 数组实现, 并应用于随机显示记录集