1. 程式人生 > >劍指offer第3:陣列中重複的數字

劍指offer第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 len(numbers)<=1:
            return False
        i=0
        while i<=len(numbers):
            m=numbers[i]
            if m==i:
                i+=1
            else:
                if numbers[i]==numbers[m]:
                    return True 
                    
                else :
                    temp=numbers[i]
                    numbers[i]=numbers[m]
                    numbers[m]=temp
                i+=1
        return False

題目2:題目描述: 
在一個長度為n+1的數組裡的所有數字都在1~n的範圍內,所以陣列中至少有一個數字是重複的。請找出陣列中任意一個重複的數字,但是不能修改輸入的陣列。

def find_dux_num(seq):
    if len(seq) <= 1 or seq is None:
        return None

    start, end = 1, len(seq) - 1  # 獲取數字1,n

    while start <= end:
        mid = (start+end) // 2  # 獲取中間數字
        count = count_num(seq, start, mid)  # 計算[start, mid]數字之間的數目

        # 當只取到一個數字時,如果該數字出現數目大於1,就是重複數字
        if start == end:
            if count > 1:
                return start
            else:
                break

        # 如果count數目 > 中間數字到起始數字之差,一定存在重複數字,繼續在這一段中求中間數比較
        if count > mid - start + 1:
            end = mid
        # 否則在後一段中求中間數比較
        else:
            start = mid + 1

    return None


def count_num(seq, start, end):
    count = 0
    for i in seq:
        if start <= i <= end:
            count += 1
    return count


if __name__ == '__main__':
    print(find_dux_num([1, 2, 3, 4, 3]))

作者:大白杏仁
連結:https://www.jianshu.com/p/b35c528e01d7
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。

https://www.jianshu.com/p/b35c528e01d7 有詳細的介紹

 

這種方法雖然不需要輔助空間O(n),但是後面每半個區間都需要遍歷整個陣列,函式countNum將被呼叫O(logn)次,每次需要O(n)的時間,因此總的時間複雜度是O(nlogn),空間複雜度為O(l)。相當於用時間換空間了。 
現在來總結下關於陣列中重複數字的問題,利用輔助空間的話,時間和空間複雜度都是O(n);利用下標於數字對應關係的話時間複雜度是O(n),空間複雜度是O(l),但是需要改變陣列;利用二分查詢類似思路的方法,時間複雜度是O(nlogn),空間複雜度O(l),所以要問清楚面試官他想要空間效率高的呢?還是時間效率高的呢?能不能改變陣列呢?一方面體現交流能力,一方面能最快的寫出答案。

還剩一個輔助空間法。