力扣原题地址:
今天刷寻找文件副本(数组重复数字),大家有兴趣可以点上看看题目要求,试着做一下。
我们直接看题解吧:
方法1,排序后再查找(时间复杂度(nlogn))
方法2,哈希集合(时间复杂度(nlogn))
方法3,原地排序(时间复杂度(1))
审题目+事例+提示:
·数组元素无顺序排列(方法1)
·未要求不可修改原数组(方法3)
·只需找到对应重复元素即可(方法2)
·题目隐含表明数组大小为n,元素在0~n-1范围中,
即数组元素与下标存在1对多的对应关系(若存在重复元素)
思路(原地排序):
1、定义变量 i =0
2、while循环,从0开始依次遍历数组,documents:
·若documents[i]==i, 即 下标与对应元素一一对应(跳过下面的语句,进行下一次循环)
·若doucments[documents[i]]==documents[i] 即下标i 对应的元素与该元素作为下标对应的元素相同,返回该元素(此时实际上是排序过的数组)
否则,交换下标i与documents[i]对应的元素。
3、若无重复元素返回-1
代码:
class Solution {
public int findRepeatDocument(int[] documents) {
int i = 0;
while(i < documents.length) {
if(documents[i] == i) {
i++;
continue;
}
if(documents[documents[i]] == documents[i]) return documents[i];
int tmp = documents[i];
documents[i] = documents[tmp];
documents[tmp] = tmp;
}
return -1;
}
}
注意:此处不适合用for循环,我们并不是直接遍历就可以,而是要满足num[i]==i,才可遍历下一位
代码(哈希集合):
class Solution {
public int findRepeatDocument(int[] documents) {
Set<Integer> hmap = new HashSet<>();
for(int doc : documents) {
if(hmap.contains(doc)) return doc;
hmap.add(doc);
}
return -1;
}
}