找出不在給定數組中的最小正整數


在leetcode上看到這道題,許多同道給出了驚艷和炫酷的解答方法。

題目:給定一個數組nums,數組中元素均為整數,返回不在nums中的最小正整數

     :type: nums -> list[int]   

   :rtype: i -> integer

   :example: nums = [2,4,7,1,-3,0,5],返回3; nums = [3,2,4,5,6] 返回 1

 

線性時間復雜度的常規實現不難:返回值一定在閉區間[1,k+1]中,創建一個長度為k+1的數組,並全部初始化為0,然后讀取原數組,將[1,k]區間內的值寫入新數組。最后再返回新數組中第一個0元素的位置 加 1.

算法一(空間復雜度O(N)):

 1 def findmissing(nums):
 2     r = [0] * (len(nums) + 1)
 3     for num in nums:
 4        if 0 < num <= len(nums):
 5             r[num - 1] = 1
 6 
 7     for i in range(len(r)):
 8         if r[i] == 0:
 9             return i + 1
10     

不難看出,空間復雜度為r數組的長度,即O(n).如果在時間復雜度不變的情況下降低空間復雜度,我們需要在原數組中記錄信息。

(1)清除無效數據,將小於等於0 和 大於數組長度的值清除;

(2)記錄 [1,len(nums)]區間內的值,將目標位置與所在位置的值交換。

算法二(空間復雜度O(1)):

def findmissing(nums):
    i = 0
    while i < len(nums):
        if 0 < nums[i] <= len(nums) and nums[nums[i]-1] != nums[i]:
            nums[nums[i]-1],nums[i] = nums[i], nums[nums[i]-1]
        else:
            i += 1
    
    for i in range(len(nums)):
        if nums[i] != i + 1:
            return i + 1
    return len(nums) + 1

除了采用交換位置的方法記錄[1,len(nums)]的值,還可以利用索引來做hash表。

算法三(空間復雜度O(1)):

 1 def findmissing(nums):
 2     # 將無效數據置為0
 3     for i in range(len(nums)):
 4         if nums[i] <=0 or nums[i] > len(nums):
 5             nums[i] = 0
 6 
 7     nums.append(0)
 8     n = len(nums)
 9 
10     for i in range(len(nums)):
11         nums[nums[i] % n] += n
12 
13     for i in range(1,len(nums)):
14         if nums[i] / n == 0:
15             return i
16     return n


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM