在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
一、按顺序排序后查找
这样的做法,就是通过for循环找到一个值为i的数值,放到下标为i的位置上,只要出现另一个位置上的值比如第 j 个位置上的值等于第 i 个位置上的值一致,说明出现重复
public static int findRepeatNumber(int[] nums, int length, int[] duplication) {
if (nums == null || length <= 0)
return -1;
// 比如:int[] nums = {2, 3, 1, 0, 2, 5, 3};
// 遍历每个位置,然后如果当前位置的数字与其下标不同
// 则进行交换位置
// 直到当前位置的数字与其小标相同
for (int i = 0; i < length; i++) {
// 循环条件,当i位置上的值不等于i时
// 如果i位置上的值不等于i,这个值可能是比i小的
// 那么在调整之后的数组中,当前位置之前肯定有出现这个值
// 而这个值的位置,其实就是当前位置的值
while (nums[i] != i) {
// 取出当前位置i的值作为下标,比如j,然后取出j位置的值
// 如果i位置的值和j位置的值一致,则存在重复的数字,直接取出
// 或者可以保存在数组中
int temp = nums[nums[i]];
//取一个临时变量temp,取(i位置上的值)的位置
//如果发现两个数是一样的,就直接返回true
if (nums[i] == temp) {
duplication[0] = temp;
return duplication[0];
}
// 交互第i个和第j个位置的两个数
swap(nums, i, nums[i]);
}
}
return -1;
}
private static void swap(int[] nums, int i, int j) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
public int findRepeatNumber(int[] nums) {
if (nums == null || nums.length <= 0)
return -1;
for (int i = 0; i < nums.length; i++) {
// 假设nums[i]=j
while (nums[i] != i) {
// 找到第 j 个位置的值
int temp = nums[nums[i]];
// 判断第 j 个位置和第 i 个位置的值是否相等
if (nums[i] == temp) {
return temp;
}
// 如果第 j 个位置的值与第 i 个位置的值不同,则交换两个位置上的值
// 这样做的目的是将数组从前往后重新排序
// 因为数组的值的范围是0 - (n-1)
// 所以重新排序之后,如果没有重复的,则可以实现
// 数组的索引与其索引上的值相等
nums[nums[i]] = nums[i];
nums[i] = temp;
}
}
return -1;
}
直接使用双层for循环查找
public boolean duplicate(int numbers[],int length,int [] duplication) {
for(int i = 0; i < length - 1; i++) { //第一层循环,遍历每一个数字
for(int j = i+1; j < length; j++) { //从i+1开始往后遍历
if(numbers[i] == numbers[j]) { //如果碰到重复的
duplication[0] = numbers[i]; //将重复的数字存入数字
return true; //返回true
}
}
}
return false; //没有重复的,返回结果false
}
网友评论