以一个大小为O(n)的哈希表为代价,时间复杂度为O(n)
// Mark: Swift
class Solution {
func findRepeatNumber(_ nums: [Int]) -> Int {
var repeatNum = 0
var numSet:Set<Int> = []
for num in nums{
if numSet.contains(num){
return num
}else{
numSet.insert(num)
}
}
return repeatNum
}
}
//Mark: C++
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
unordered_map<int,bool> dic;
for (int &num: nums){
if (dic[num]) return num;
dic[num] = true;
}
return -1;
// unordered_map<int, bool> dic;
// for (int &num: nums){ //&则使用原始数据 不带&则使用新建的副本 耗时更久
// if (dic[num]) return num;
// dic[num] = true;
// }
// return -1;
}
};
方法2:
鸽巢原理,因为出现的元素值 < nums.size(); 所以我们可以将见到的元素 放到索引的位置,如果交换时,发现索引处已存在该元素,则重复。O(N) 空间O(1)
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
//鲁棒性
if (nums.empty()) {return 0;}
for (int &num: nums){
if (num < 0 || num > nums.size()) {
return 0;
}
}
//鸽巢原理
for (int i=0; i<nums.size(); ++i){
while(nums[i] != i){
if (nums[i] == nums[nums[i]]){
return nums[i];
}
//swap
int temp = nums[i];
nums[i] = nums[temp];
nums[temp] = temp;
}
}
return -1;
}
};
方法3: 排序法,看前后元素是否相等。 O(NlogN) 空间 O(1)
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
if (nums.empty()) {return 0;}
for (int &num: nums){
if (num < 0 || num > nums.size()) {
return 0;
}
}
//排序法
sort(nums.begin(),nums.end());
for (int i = 0; i<nums.size(); i++){
if (nums[i] == nums[i+1]){
return nums[i];
}
}
return -1;
}
};