数组中重复的数字
题目:
在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但有不知道有几个数字重复,也不知道每个数字重复了几次。
请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3}, 那么对应的输出是重复的数字2或者3。
基于平时业务开发的思维,从头到尾遍历数组,借助一个额外的空间哈希表,判断哈希表是否已包含此数字,没有这个数字就把此数字放入哈希表,如果已包含,则直接返回,上代码。
public static Integer findRepeatingNum(int nums[]){
//以空间换时间
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i=0;i<nums.length;i++){
//如果已存在,则直接返回
if(map.get(nums[i])!=null){
return nums[i];
}
//否则,放入map中
map.put(nums[i],nums[i]);
}
//默认返回空值,即无重复数字
return null;
}
上述代码额外使用一个O(n)的存储空间,此外我们还有一个更优解,已知数字范围0~n-1,数组长度为n,升序排列,效果如下:
输入{2,3,1,0,2,5,3}
升序{0,1,2,2,3,3,5}
故我们可以通过从头到尾依次扫描数组,当扫描到下标为i的数字时,首先比较这个数字(用m表示)是否等于i,如果是则扫描下个数字,如果不是,则再拿它和第m个数字进行比较,如果它和第m个数字相等,即找到了重复数字(因为该数字在下标i和m都出现过了),如果它和第m个数字不想等,就把下标第i个数字和第m个数字进行交换,把m放到属于它的位置,接下来再重复比较,交换的过程,直至我们发现一个重复数字。上代码。
public static Integer findRepeatingNumNew(int nums[]){
for(int i=0;i<nums.length;i++){
while(nums[i]!=i){
int temp = nums[i];
//如果nums[i]等于nums[m],找到重复数字
if(temp == nums[temp]){
return temp;
}
//交换两者的位置
nums[i] = nums[temp];
nums[temp] = temp;
}
}
return null;
}
总结:
- 面试是表现自己的机会,不要当成考试,不要紧张,尽可能的表达自己的想法和思路.
- 学会引导面试官,聊自己擅长的领域,从面试官的话题延伸到自己擅长的方向.