劍指 Offer——面試題 3-1
題目
找出數組中的重複數字
在一個長度爲n
的數組裏的所有數字都在0 ~ n - 1
的範圍內,數組中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次,請找出數組中任意一個重複的數字
輸入樣例
[2, 3, 1, 0, 2, 5, 3]
輸出樣例
2 或 3
思路
這道題是一個很常見的數組問題,解法也有很多種,
首先想到的我們可以通過暴力方法(手動狗頭),我們排序這個數組,然後遍歷一遍數組看看有沒有連續的兩個相同的數字;另外,我們可以通過哈希表的特性,在遍歷數組的過程中,每次檢測哈希表中是否存在這個數字,不存在就放入哈希表中,存在就直接返回這個重複元素
那有沒有什麼比較巧妙的方法呢嘿嘿
這裏提供一種方法,首先,如果這個數組沒有重複元素,那麼它一定會包含0 ~ n - 1
中的所有數字,那麼我們從頭開始遍歷這個數組,每遇到一個數,就檢測它是不是在自己的位置上,即數組爲nums
,循環變量是i
,當我們遍歷到nums[i]
時,我們檢測nums[i] == i
,如果不相等,我們就把nums[i]
放到nums[i]
的位置上,這樣,在繼續遍歷的過程中,如果第二次遇到一個相同的數字,就會出現nums[i] == nums[nums[i]]
這種情況,此時就是重複的數字了!代碼如下:
代碼
#include <iostream>
using namespace std;
bool dublicate(int numbers[], int length) {
if (numbers == nullptr || length <= 0)
return false;
for (int i = 0; i < length; ++i) {
while (numbers[i] != i) {
if (numbers[i] == numbers[numbers[i]])
return true;
int item = numbers[numbers[i]];
numbers[numbers[i]] = numbers[i];
numbers[i] = item;
}
}
return false;
}
int main() {
int a[5] = { 1, 2, 3, 3, 4 };
if (dublicate(a, 5))
cout << "yes" << endl;
else
cout << "no" << endl;
}