1. 题目
给出一个数组 nums 包含 n + 1
个整数,每个整数是从 1 到 n (包括边界),保证至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
样例 1:
输入:
[5,5,4,3,2,1]
输出:
5样例 2:
输入:
[5,4,4,3,2,1]
输出:
4
注意事项
1.不能修改数组(假设数组只能读)
2.只能用额外的O(1)的空间
3.时间复杂度小于O(n2)
4.数组中只有一个重复的数,但可能重复超过一次
2. 解题
- 把数值作为下标,跟下标处的数交换,直到相等为止
class Solution {
public:int findDuplicate(vector<int> &nums) {int i = 0;while(nums[i] != nums[nums[i]])swap(nums[i], nums[nums[i]]);return nums[i];}
};
or 位运算swap
class Solution {
public:int findDuplicate(vector<int> &nums) {int i = 0;while(nums[i] != nums[nums[i]])myswap(nums[i], nums[nums[i]]);return nums[i];}inline void myswap(int& a, int& b){a ^= b ^= a ^= b;}
};
100% 数据通过测试
总耗时 1561 ms
您的提交打败了 90.80% 的提交!
- 快慢指针
class Solution {
public:int findDuplicate(vector<int> &nums) {int fast = 0;int slow = 0;do{fast = nums[nums[fast]];slow = nums[slow];}while(fast != slow);slow = 0;while (slow != fast) {fast = nums[fast];slow = nums[slow];}return fast;}
};
- 标记为负数法
class Solution {
public:int findDuplicate(vector<int> &nums) {int idx, i;for(i = 0; i < nums.size(); ++i){idx = abs(nums[i]);if(nums[idx] > 0)nums[idx] = -nums[idx];elsereturn idx;}return -1;}
};