题目描述:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/
这种题两种做法,占坑法和哈希法,时间复杂度都为O(n),空间复杂度前者为O(1),后者为O(n)
下面代码为不考数字虑越界情况,若考虑有非法数字,单独遍历一次判断,不能放到主循环里。
占坑法:
需要不停交换特定两个数,注意,java里的交换需要数组做参数,普通变做参数是传值,实际变量不会交换:
java里交换两个数:https://www.cnblogs.com/xzh0717/p/11132864.html
class Solution {
public int findRepeatNumber(int[] nums) {
int n = nums.length;
for(int i = 0; i < n; ++i){
//不停把当前位置的数换到它正确的位置上
while (i != nums[i] && nums[i] != nums[nums[i]]){
swap(nums, i, nums[i]);
}
if(i != nums[i] && nums[i] == nums[nums[i]])
return nums[i];
}
return -1;
}
//不能int a, int b作为参数
public void swap(int nums[], int a, int b){
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
}
哈希法:
class Solution {
public int findRepeatNumber(int[] nums) {
int n = nums.length;
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < n; ++i){
if(map.containsKey(nums[i]))
return nums[i];
else
map.put(nums[i], 1);
}
return -1;
}
}
用HashSet好一点:HashSet的添加元素方法add(),返回bool型,不能重复添加
class Solution {
public int findRepeatNumber(int[] nums) {
int n = nums.length;
Set<Integer> set = new HashSet<>();
for(int i = 0; i < n; ++i){
//set的add方法返回bool值,不能添加的话,就已经有了
if(!set.add(nums[i]))
return nums[i];
else
set.add(nums[i]);
}
return -1;
}
}