剑指Offer03 数组中重复的数字
记录四种解法,逐步优化
题目
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
/**
* @version V1.0
* @ClassName:Offer03
* @Description: TODO
* @author:Daniel
* @date:2021/1/19 上午10:00
*/
public class Offer03 {
public static void main(String[] args) {
int[] nums = new int[]{
2, 3, 1, 0, 2, 5, 3};
System.out.println(findRepeatNumber4(nums));
}
// 数组中重复的数字 (使用hashtable,编译不通过)
public static int findRepeatNumber1(int[] nums) {
Hashtable hashtable = new Hashtable();
for (int i = 0; i < nums.length; i++) {
if (hashtable.get(nums[i]) == null) {
hashtable.put(nums[i], i);
} else {
return nums[i];
}
}
return -1;
}
// 数组中重复的数字(使用hashset编译可以通过,但是效率不高,该解法遍历了数组中所有的数字)
public static int findRepeatNumber2(int[] nums) {
HashSet<Integer> integers = new HashSet<>();
for (int num : nums) {
if (!integers.contains(num)) {
integers.add(num);
} else {
return num;
}
}
return -1;
}
// 使用HashSet的优化,提前跳出遍历
public static int findRepeatNumber3(int[] nums) {
HashSet<Integer> set = new HashSet<>();
int repeat = -1;
for (int num : nums) {
if (!set.add(num)) {
repeat = num;
break; // 如果有重复,则直接跳出遍历
}
}
return repeat;
}
// 实现剑指offer上的思路,在所给的数组上进行操作,空间复杂度为O(1)
public static int findRepeatNumber4(int[] nums) {
// 首先保证程序的健壮性
for (int num : nums) {
if (num < 0) {
return -1;
}
}
// 遍历数组中所有的元素,使每一个元素放在对应的下标位置
for (int i = 0; i < nums.length; i++) {
while (nums[i] != i) {
int m = nums[i];
if (nums[i] == nums[m]) {
return m;
}
swap(nums, i, m);
}
}
return -1;
}
public static void swap(int[] nums,int index1, int index2) {
int temp = 0;
temp = nums[index1];
nums[index1] = nums[index2];
nums[index2] = temp;
}
}