Leetcode面試題3-面試題數組中重複的數字

題目描述

找出數組中重複的數字。python

在一個長度爲 n 的數組 nums 裏的全部數字都在 0~n-1 的範圍內。數組中某些數字是重複的,但不知道有幾個數字重複了,也不知道每一個數字重複了幾回。請找出數組中任意一個重複的數字
示例 1:算法

輸入:
[2, 3, 1, 0, 2, 5, 3]
輸出:2 或 3

該題目的難度級別爲Easy。數組

思路1

最直觀的方式可能就是排序+遍歷的方式, 根據這個思路能夠很容易的寫出代碼數據結構

def findRepeatNumber(nums: List[int]) -> int:
    if nums == None or len(nums) < 2:
        return 
    nums.sort()
    
    for i in range(1, len(nums)):
        # 只要找到就能夠返回
        if nums[i] == nums[i-1]:
            return nums[i]

排序的時間複雜度爲$O(nlogn)$,遍歷的時間複雜度爲$O(n)$,即算法的時間複雜度爲$O(nlogn)$,空間複雜度爲$O(1)$。數據結構和算法

思路2

使用字典做爲計數器,只要某個元素的已經存在於字典中就能夠直接返回。按照這個思路能夠寫出以下代碼學習

def findRepeatNumber(nums: List[int]) -> int:
    if nums == None or len(nums) < 2:
        return 
    dicts = {}
    
    for i in nums:
        # 只要找到就能夠返回
        if i in dicts:
            return i
        dicts[i] = 1

相比於第一種算法,該算法以空間換時間。由於只有一次循環,時間複雜度爲$O(n)$,空間複雜度爲$O(n)$。優化

優化算法

上面2中思路都是比較容易想到的,那麼有沒有不使用額外空間,而且時間複雜度爲$O(n)$的算法呢。spa

每次換一種思路時,咱們須要從新去思考題目,而不是在已有的思路上糾結。
若是數組nums沒有重複,那麼nums的索引所構成的集合和nums中的元素構成的集合是相等的(從集合的角度上來看,不考慮順序)。即對於任意一個索引,都有惟一的元素與它相等,相對應3d

但若是nums包含重複元素,那麼對於部分索引,將會對應多個相同元素,好比nums = [2, 3, 1, 0, 2, 5, 3]code

索引爲2的對應數組中的2個2,索引爲3的對應數組中的2個3。咱們能夠依次的將每一個元素放到它對應的索引位置,而若是該元素和它對應索引位置的元素相等,說明該元素重複。

image.png
按照這個思路, 能夠寫出以下的代碼

def findRepeatNumber(nums: List[int]) -> int:
    if nums == None or len(nums) < 2:
        return 
    for i in range(len(nums)):
        # 索引和對應元素不一致,調整元素位置,直至索引與元素匹配或者找到重複元素
        while i != nums[i]:
        
            # 若是當前元素對應的索引位置的值與當前元素相等
            if nums[i] == nums[nums[i]]:
                return nums[i]
                
            # 交換nums[i]和i位置的值
            temp = nums[i]
            nums[i], nums[temp] = nums[temp], nums[i]

上述代碼雖然包含了2次循環,但每一個位置均可以在有限次內結束。所以總的時間複雜度爲$O(n)$,並不須要使用額外的空間,空間複雜度爲$O(1)$。

總結

經歷了慘痛的教訓,終於決定要開始認真刷題了。以前一直是處於間歇期放棄的狀態,致使如今基本上是從零開始了。我會盡量把本身作過的題目進行一些總結,因爲本人對於數據結構和算法的學習有限,大佬勿噴。

相關文章
相關標籤/搜索