Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Note:
- You must not modify the array (assume the array is read only).
- You must use only constant, O(1) extra space.
- Your runtime complexity should be less than
O(n2)
. - There is only one duplicate number in the array, but it could be repeated more than once.
分析:
方法一:方法1:依次遍历数组,判断当前遇到的元素是否在hashmap中,若在则返回这个元素,若不在,则把该元素放到hashmap中,继续遍历。
/**
* Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive),
* prove that at least one duplicate number must exist.
* Assume that there is only one duplicate number, find the duplicate one.
* 方法1:依次遍历数组,判断当前遇到的元素是否在hashmap中,若在则返回这个元素,若不在,则把该元素放到hashmap中,
* 继续遍历。
* @param nums
* @return
*/
public int findDuplicate(int[] nums) {
int length = nums.length;
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i=0;i<length;i++){
if(map.containsKey(nums[i])){
return nums[i];
}else{
map.put(nums[i],1);
}
}
return -1;
}
方法二:方法2:依次遍历数组,判断当前遇到的元素m减去1是否等于下标i,若相等则i++继续扫描下一个元素;若不等则判断A[m]是否与m-1相等,
若相等则找到了重复的元素,若不等则交换A[m-1]与A[i],然后继续判断当前遇到的新的元素m减去1是否等于下标i。与剑指offer中的面试题51不同。
剑指offer:数组中存的是0到n-1的数字;
leetcode:数组中存的是1到n+1的数字。
所以leetcode中数组下标为i的要存i+1的元素值,剑指offer中下标为i的存i的元素值就好了。
/**
* 与剑指offer中的面试题51不同。
* 剑指offer:数组中存的是0到n-1的数字;
* leetcode:数组中存的是1到n+1的数字。
* 所以leetcode中数组下标为i的要存i+1的元素值。
* 方法2:依次遍历数组,判断当前遇到的元素m减去1是否等于下标i,若相等则i++继续扫描下一个元素;若不等则判断A[m]是否与m-1相等,
* 若相等则找到了重复的元素,若不等则交换A[m-1]与A[i],然后继续判断当前遇到的新的元素m减去1是否等于下标i。
* @param nums
* @return
*/
public int findDuplicate2(int[] nums) {
int length = nums.length;
int m;
int temp;
for(int i=0;i<length;i++){
m = nums[i];
while(m-1 != i){
if(nums[m-1] == m){//说明此时遇到了两个下标存储的元素值都是m
return nums[i];
}else{//若不等就把m放到应该对应的下标位置
temp = nums[m-1];
nums[m-1] = nums[i];
nums[i] = temp;
}
m = nums[i] ;
}
}
return -1;
}