找出数组中一个重复的数字
数组大小为n+1,数组中数字大小为[1,n],只有一个重复
分析这个题发现有n+1个整数,数组下标在[0,n],数字大小在[1,n],也就是数组中最起码有一个重复的数,假设只有一个重复的值(记住这种时候比的是数组,下标用num[i]-1记录)
(1)在一个排序好的数组中找到重复的数字非常容易,排序的时间复杂度是O(nlogn)。
(2)然后也可以利用哈希表来解决这个问题,扫描到一个数字时利用O(1)的复杂度来看是否哈希表中中已经包含了该数字,这样的话只要遍历一遍就可以得到,但这样是以一个空间复杂度为O(n)的哈希表来为代价的。也就是遍历数组,并建立一个boolean数组记录这个数字是否遍历过(这里使用的最大原因是数组的内容长度在0到n-1范围内,否则可以利用一个map来记录),找到返回即可。
(3)所以最好想一个空间复杂度为O(1)也就是不用额外分配空间的算法。因为数组在1到n的范围内,所以如果没有重复,大小为i的数字排序好会出现在i-1的位置上,而且数字0是不会出现的,循环数组进行数组遍历,这个题肯定不会缺失数,所以比较i和arr[i]-1是否相等,相等则i++,不相等则交换arr[i]和arr[arr[i]],在交换之前要看会出现这两个值相等的情况,只要出现说明这个数字就是那个重复的数字。时间复杂度为O(n)。空间复杂度为O(1)。
(4)如果数组不允许更改,则使用partition算法。
class Solution {
public int findDuplicate(int[] nums) {
if(nums==null || nums.length==0) return 0;
int i=0;
int n=nums.length;
while(i<n){
int x=nums[i]-1;
if(x!=i){
if(nums[x]==nums[i]) return nums[i];
else<