版权声明:个人博客:转载请注明出处 https://blog.csdn.net/weixin_43161811/article/details/82534910
题目描述
在长度为n的数组中,所有的元素都是0到n-1的范围内。 数组中的某些数字是重复的,但不知道有几个重复的数字,也不知道重复了几次,请找出任意重复的数字。 例如,输入长度为7的数组{2,3,1,0,2,5},那么对应的输出的是第一个重复的数字2。
解题思路
这种数组元素在 [0, n-1] 范围内的问题,可以将值为 i 的元素放到第 i 个位置上。
以 (2, 3, 1, 0, 2, 5) 为例:
//遍历索引0:
position-0 : (2,3,1,0,2,5) // 0!=2 与索引2的值对换 2<-> 1
(1,3,2,0,2,5) // 0!=1 与索引1的值对换1<-> 3
(3,1,2,0,2,5) // 0!=3 与索引3的值对换 3<-> 0
(0,1,2,3,2,5) // 0==0 归位
//遍历索引1:
position-1 : (0,1,2,3,2,5) // 1==1
//遍历索引2:
position-2 : (0,1,2,3,2,5) // 2==2
遍历到位置 4 时,该位置上的数为 2,但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复。
public class Test {
public boolean findDuplicateNumber(int[] nums, int length, int[] duplication) {
// 判断数组合理性
if (nums == null || length <= 0)
return false;
// { 2, 3, 1, 0, 2, 5 };
for (int i = 0; i < length; i++) {
// 这里为什么用while而不用if
// if只会判断一次 而需求是需要我们不断的判断nums[i] 是否== i 试一下?
while (nums[i] != i) {
if (nums[i] == nums[nums[i]]) {
// 查到 存入duplication 返回 这里只实现查到任意一个重复数字 查多个可以再修改
duplication[0] = nums[i];
return true;
}
// 交换
swap(nums, i, nums[i]);
}
}
return false;
}
// 两数交换位置
private void swap(int[] nums, int i, int j) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
// 测试
public static void main(String[] args) {
int[] nums = { 2, 3, 1, 0, 2, 5 };
int[] duplication = { -1 };// 防止空指针
boolean ok = new Test().findDuplicateNumber(nums, nums.length, duplication);
if (ok) {
System.out.println("找到重复的数字是:" + duplication[0]);
for (int i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
} else {
System.out.println("没有找到重复的数字");
}
}
}