在一個長度爲 n 的數組 nums 裏的所有數字都在 0~n-1 的範圍內。數組中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出數組中任意一個重複的數字。
示例 1:
輸入:
[2, 3, 1, 0, 2, 5, 3]
輸出:2 或 3
限制:
2 <= n <= 100000
解法一
使用兩個循環遍歷數組,發現相同元素就返回,否則返回 -1。當然了,這種做法碰到龐大一點的數組直接超時,不可取。
public int findRepeatNumber(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
for (int j = i+1; j < nums.length; j++) {
if (nums[i] == nums[j]) {
return nums[i];
}
}
}
return 0;
}
解法二
Set 集合不能有重複元素,遍歷數組,將走過的元素保存入Set,如果出現無法添加的情況,證明該元素在Set中已存在,返回該元素;否則返回-1
public int findRepeatNumber(int[] nums) {
Set<Integer> set = new HashSet<Integer>();
for (int num : nums) {
if(!set.add(num)) {
return num;
}
}
return -1;
}
解法三
原地置換算法,利用數組下標來匹配對應的元素,從前往後遍歷數組,每個元素都要求下標與元素的值一一對應,如果在調換位置的過程中發現該位置的元素與別的位置的元素是相同的,那麼就說明該數字重複,直接返回該數字。
public static int findRepeatNumByNon(int[] nums){
for (int i = 0; i < nums.length; i++){
//將數字與下標對應起來
while (nums[i] != i){
int temp = nums[i];
//如果準備移動的數字已經等於對應位置上的數字則說明數字重複
if(temp == nums[temp]) return temp;
nums[i] = nums[temp];
nums[temp] = temp;
}
}
return -1;
}