劍指offer 面試3題


面試3題:

題:數組中重復的數字

題目:在一個長度為n的數組里的所有數字都在0到n-1的范圍內。 數組中某些數字是重復的,但不知道有幾個數字是重復的。也不知道每個數字重復幾次。請找出數組中任意一個重復的數字。 例如,如果輸入長度為7的數組{2,3,1,0,2,5,3},那么對應的輸出是第一個重復的數字2。

解題思路一:先把輸入數組排序,然后從排序后的數組中從前往后找。

解題代碼:

# -*- coding:utf-8 -*-
class Solution:
    # 這里要特別注意~找到任意重復的一個值並賦值到duplication[0]
    # 函數返回True/False
    def duplicate(self, numbers, duplication):
        # write code here
        if numbers==None or len(numbers)<=1:
            return False
        for i in range(len(numbers)):
            if numbers[i]<0 or numbers[i]>len(numbers)-1:
                return False
            
        numbers.sort()
        for i in range(len(numbers)-1):
            if numbers[i]==numbers[i+1]:
                duplication[0]=numbers[i]
                return True
        return False

 

解題思路二:使用輔助空間:哈希表。時間復雜度為O(n),空間復雜度為O(n)

解題代碼:

# -*- coding:utf-8 -*-
class Solution:
    # 這里要特別注意~找到任意重復的一個值並賦值到duplication[0]
    # 函數返回True/False
    def duplicate(self, numbers, duplication):
        # write code here
        if numbers==None or len(numbers)<=1:
            return False
        
        usedDic=set() #集合
        for i in range(len(numbers)):
            if numbers[i]<0 or numbers[i]>len(numbers)-1:
                return False
            if numbers[i] not in usedDic:
                usedDic.add(numbers[i])
            else:
                duplication[0]=numbers[i]
                return True
        return False

 

解題思路三:重排數組:從頭到尾掃描數組的每個數字,當掃描到下標為i的數字時,首先比較這個數字(假設為m)是否等於i,如果是,接着掃描下一個數字;如果不是,那么再將它和下標為m的數字對比,如果兩者不相等,就把它和第m個數字交換,把m放到屬於它的位置,如果兩者相等,那么就找到了一個重復的數字。重復這個過程,知道發現一個重復的數字。

解題代碼:(根據代碼分析復雜度:所有操作都在輸入數組上進行,不需要額外分配空間,因此空間復雜度為O(1);盡管代碼中有一個兩重循環,但是每個數字最多只要交換兩次就能找到它自己的位置,因為總的時間復雜度為O(n))

# -*- coding:utf-8 -*-
class Solution:
    # 這里要特別注意~找到任意重復的一個值並賦值到duplication[0]
    # 函數返回True/False
    def duplicate(self, numbers, duplication):
        # write code here
        if numbers==None or len(numbers)<=1:
            return False
        
        for i in range(len(numbers)):
            if numbers[i]<0 or numbers[i]>len(numbers)-1:
                return False
        
        for i in range(len(numbers)):
            while (numbers[i]!=i):
                if numbers[i]==numbers[numbers[i]]:
                    duplication[0]=numbers[i]
                    return True
                else:
                    temp=numbers[i]
                    numbers[i]=numbers[temp]
                    numbers[temp]=temp
        return False

 

 

拓展:不修改數組找出重復的數字。

'''
拓展:不修改數組找出重復的數字。
在一個長度為n+1的數組里的所有數字都在1~n的范圍內,所以數組中至少有一個數字是重復的。請找出數組中任意一個重復的數字,
但不能修改輸入的數組,例如輸入長度為8的數組[2,3,5,4,3,2,6,7],那么對應的輸出是重復的數字為2或3。
'''

# 方法一:利用哈希表,時間復雜度O(n),空間復雜度O(n)
# 方法二:二分查找的變形,如下,時間復雜度O(nlogn),空間復雜度為O(1)

class Solution:
    def duplicate(self, numbers):
        # write code here
        if not numbers or len(numbers)<=0:
            return -1
        start=1
        end=len(numbers)-1
        while start<=end:
            middle=(end-start)//2+start
            count=self.countRange(numbers,len(numbers),start,middle)
            if end==start:
                if count>1:
                    return start
                else:
                    break
            if count>middle-start+1:
                end=middle
            else:
                start=middle+1
        return -1

    def countRange(self,numbers,length,start,end):
        '''
        計算數組中的元素大於等於start,小於等於end的元素的個數
        '''
        if not numbers:
            return 0
        count=0
        for  i in range(length):
            if numbers[i]>=start and numbers[i]<=end:
                count+=1
        return count

if __name__=="__main__":
    print(Solution().duplicate([2,3,5,4,3,2,6,7]))

 


免責聲明!

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



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