题目(题目及解法参考来源与力扣!)
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
解题思路
solution one: 应该是菜鸡第一个思路,两个for循环便利数组,判断相等标记,return.
class Solution {
public int findRepeatNumber(int[] nums) {
int result = 0;
int flag = 0;
for(int i = 0; i < nums.length; ++i)
{
for(int j = i + 1; j < nums.length; ++j)
{
if(nums[i] == nums[j])
{
result = nums[i];
flag = 1;
break;
}
if(flag == 1)
break;
}
}
return result;
}
}
solution two. 利用集合。
class Solution {
public int findRepeatNumber(int[] nums) {
Set<Integer> sets = new HashSet<Integer>();
for(int num : nums)
{
if(!sets.add(num))
return num;
/*
if(sets.contains(num))
repeat = num;
sets.add(num);
*/
}
return -1;
}
}
attention:
- HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
- HashSet 允许有 null 值。
- HashSet 是无序的,即不会记录插入的顺序。
- HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。
- HashSet 实现了 Set 接口。
- HashSet 中的元素实际上是对象,一些常见的基本类型可以使用它的包装类。
8. 添加元素可以使用 add() 方法:
9. contains() 方法来判断元素是否存在于集合当中:
10. remove() 方法来删除集合中的元素:
11. 删除集合中所有元素可以使用 clear 方法:
12. 计算 HashSet 中的元素数量可以使用 size() 方法:
13. 可以使用 for-each 来迭代 HashSet 中的元素。
14.
public static void hashSetTest(){
HashSet<String> sites = new HashSet<String>();
sites.add("google"); //add方法添加元素
sites.add("Runoob");
sites.add("Taobao");
sites.add("Zhihu");
sites.add("Runoob"); //重复元素不会被添加
System.out.println(sites);
System.out.println("---------------------------------");
System.out.println(sites.contains("Taobao")); //contains方法检测元素是否存在
System.out.println("---------------------------------");
sites.remove("Taobao"); //remove方法删除元素,成功返回true,否则为true
System.out.println(sites);
System.out.println("---------------------------------");
System.out.println(sites.size()); //size方法检测集合中元素数量
System.out.println("---------------------------------");
for(String i : sites){
System.out.println(i); //注意,Set中元素实际上是对象,所以循环可以用for-each迭代HashSet中的元素
}
System.out.println("---------------------------------");
sites.clear(); //clear方法删除集合所有元素
System.out.println(sites);
}
运行结果:
solution three:原数交换
题目中说:在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。也就是说如果有相同的数字,且都在0~n-1 的范围内,那么索引与索引对应值的数量一定存在一对多的关系。遍历中,第一次遇到数字 a 时,将其交换至索引 a 处;而当第二次遇到数字 a 时,一定有 nums[a] = a,此时即可得到一组重复数字。
public static int findRepeatNumber2(int[] nums){
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]; // 数字与索引数值不同,交换到 a = nums[a]处
nums[i] = nums[temp];
nums[temp] = temp;
}
return -1;
}