1、题目描述
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
- 示例
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
2、解题思路
求解给定数组中任一的重复值即可
3、代码
- 方法一
HashSet<Integer> set =new HashSet<Integer>();
int res = -1;
for (int num : nums){
if (!set.add(num)){
res = num;
break;
}
}
return res;
利用了HashSet集合的去重功能,从数组的开始向集合中添加元素,集合中已经存在的元素即是重复的元素,返回即可。这种方法比较好,时间复杂度 n,空间复杂度 1
- 方法二
int[] arr = new int[Arrays.stream(nums).max().getAsInt()+1];
int res = -1;
for (int num : nums){
arr[num]++;
if (arr[num] > 1){
res = num;
break;
}
}
return res;
利用数组的流运算求出数组的最大值,新建一个数组 arr,在初始化时全为 0,将 nums数组的元素作为 arr 的下标,存储的值 ++,arr 存储的值大于 1即重复的值
- 方法三
int[] arr = new int[nums.length];
在方法二的基础上进行优化,因为数组 nums 里的所有数字都在 0~n-1 的范围内,所以省去了流运算求取最大值的时间
- 方法四
nums = Arrays.stream(nums).sorted().toArray();
int res = -1;
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] == nums[i+1]){
res = nums[i];
break;
}
}
return res;
利用流运算进行排序,相邻的两个相等就是重复的值
- 方法五
int res = -1;
boolean flag = true;
for (int i = 0; i < nums.length && flag; i++){
for (int j = i + 1; j < nums.length; j++){
if (nums[i] == nums[j]){
res = nums[i];
flag = false;
}
}
}
return res;
暴力破解法,遍历到相等的就返回结果,时间复杂度最大,空间复杂度 1
- 方法六
int i = 0;
while(i < nums.length){
if(nums[i] == i){
i++;
continue;
}
if(nums[nums[i]] == nums[i]){return nums[i];}
int temp = nums[i];
nums[i] = nums[temp];
nums[temp] = temp;
}
return -1;
最优秀的方法原地交换[操作],nums 数组的值存储到 nums下标值进行交换,否则就证明是重复值,返回即可
4、心得
通过不断的编写,锻炼了自己对语言的认识,语言和算法是用于解决实际问题的工具
闲暇时间对算法的优化,,提升了自己对算法编程的兴趣,思维有所提高