剑指Offer 03题
找出数组中重复的数字
-
题目描述:
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
-
思路一:临时数组
- 申请一个临时数组,长度为num.length;
- 遍历数组nums;如果nums[i]是几,就给临时数组第几个位置加1;
- 判断临时数组的元素,如果大于1,则出现重复值。
-
思路二:先排序再查找
- ①利用Arrays.sort()方法对数组进行排序;
- ②如果有重复的值,排序之后一定是相邻的数,比较相邻两个数是否相等即可。
- ③注意:从1位置开始遍历,每次比较该位置与前一个位置的数是否相等;因为如果从0位置开始遍历,只能与后一个位置的数比较,这样到第nums.length-1位置比较时,会越界。
-
思路三:放在指定位置
- ① 对数组归位,遍历该数组;
- ②判断nums[i]是不是i(即判断第i个位置的数是不是i),如果不是,比较它和第num[i]个位置上的数,即判断nums[i]和nums[nums[i]];
- ③若nums[i]和nums[nums[i]]相等,则找到重复的值,返回nums[i];若不相等,则交换(第i位置的数与第num[i]位置上的数);
- ④再重复这个比较,直到找到重复的值。
-
代码实现:
import java.util.Arrays;
public class Test03 {
public static void main(String[] args) {
Test03 test03 = new Test03();
int[] a = {2, 3, 1, 0, 2, 5, 3};
//System.out.println(test03.findRepeatNumber1(a));
//System.out.println(test03.findRepeatNumber2(a));
System.out.println(test03.findRepeatNumber3(a));
}
//1.临时数组
public int findRepeatNumber1(int[] nums) {
int[] arr = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
arr[nums[i]]++;
if (arr[nums[i]] > 1) {
return nums[i];
}
}
return -1;
}
//2.先排序再查找
public int findRepeatNumber2(int[] nums) {
Arrays.sort(nums);
//从1位置开始遍历,每次比较该位置与前一个位置的数是否相等
for (int i = 1; i < nums.length; i++) {
if (nums[i] == nums[i - 1]) {
return nums[i];
}
}
return -1;
}
//3.放在指定位置
public int findRepeatNumber3(int[] nums){
for(int i = 0; i < nums.length; i++){
if(nums[i] != i){
if(nums[nums[i]] == nums[i]){
return nums[i];
}else{
int temp = nums[i];
nums[i] = nums[temp];
nums[temp] = temp;
}
}
}
return -1;
}
}