# Question Description

```
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Note:
You must not modify the array (assume the array is read only).
You must use only constant, O(1) extra space.
Your runtime complexity should be less than O(n2).
There is only one duplicate number in the array, but it could be repeated more than once.
```

# Solutions

## Approach #1 - [Brute Force]

#### status :

- [ ] AC
- [x] TLE

#### Intuition

```
Idea: Scan array for each number and try to find dup
```

#### Algorithm

```
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
for i in xrange(len(nums)):
for j in xrange(len(nums)):
if nums[i] == nums[j] and i != j:
return nums[i]
return -1
```

## Approach #2

#### status :

- [x] AC
- [ ] TLE

#### Intuition

```
Idea:
for the numbers in range [1,n], we find the mid - middle value of the range, then we do a count
count(nums <= mid)
if count is less then mid, there are dups in the vals above mid, otherwise dups in the lower range
O(nlgn)
```

#### Algorithm

```
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
L,R = 1,len(nums)-1
while L < R:
mid = L + (R-L)/2
cnt = sum([1 for x in xrange(len(nums)) if nums[x] <= mid])
if cnt <= mid:
L = mid + 1
else:
R = mid
return L
```

## Approach #3

#### status :

- [x] AC
- [ ] TLE

#### Intuition

```
Idea:
The idea is to treat the array as linked lists, where each value at nums[i] is the pointer to next value
use regular fast&slow pointer, when fast catches slow, slow is half way through the circle
then start from begining using beg(or fast as in the code) - it will converge with slow at the dup number
*credit :
https://discuss.leetcode.com/topic/25913/my-easy-understood-solution-with-o-n-time-and-o-1-space-without-modifying-the-array-with-clear-explanation
and
user : wave [code below]
```

#### Algorithm

```
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
slow = nums[0]
fast = nums[nums[0]]
while (slow != fast):
#slow = slow->next
slow = nums[slow]
#fast = fast->next->next
fast = nums[nums[fast]]
fast = 0
while (fast != slow):
fast = nums[fast]
slow = nums[slow]
return slow
```