题目 : 输入长度为n的数组nums,且nums中的元素都在区间【0,n-1】之内。找出数组中任意一个重复的数字。
输入:
[2,3,1,0,2,5,3] n=7
输出:2或3
方法1 : 原地交换
空间复杂度 o(1),时间复杂度O(N)只需要遍历一次数组。
这里考察的是数组的特性, 索引和值是一一对应的关系,类似一个字典(哈希表);
因为根据题意,长度为n的数组,元素只能在区间【0, n-1】,那么一个值和索引是一对多的关系。一个值,多个索引可以找到: nun[x] = num[y]
我们可以通过交换数组元素,使得nums[i] = i,即索引对应一个值。作用于字典等价。
如果nums[i] == nums[nums[i]]成立,那么可以找到了数组中的重复的元素,返回nums[i]
举例子:原地遍历数组,如果num[i] = I contine;
元素 num[i]: 2 3 1 0 2 5 3
索引 i: 0 1 2 3 4 5 6
Step01: num[0] = 2;---》 交换 索引 0 和 索引nums[2]
元素 num[i]: 1 3 2 0 2 5 3
索引 i: 0 1 2 3 4 5 6
Step02: num[1] = 3 交换索引 1 和 索引 nums[3]
元素 num[i]: 1 0 2 3 2 5 3
索引 i: 0 1 2 3 4 5 6
Step03: num[2] = 2 continue;
Step04: num[3] = 3 conitune;
Step05: num[4] = 2 => num[4] = num[2] return num[2];
Step06: num[5] = 5;
Step07: num[6]= 3 ==> num[6]= num[3] return num[3];
我的答案:
class Solution {
public int findRepeatNumber(int[] nums) {
for (int i = 0; i < nums.length; i++) {
if (nums[i] == i) {
continue;
}
if (nums[i] == nums[nums[i]] ){
return nums[i];
}
swap(nums,i, nums[i]);
}
return -1;
}
private static void swap(int[] nums,int i, int j){
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
}
}