LC287 Solution


  • 0
    E

    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
    

Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.