leetcode 287. 尋找重複數【Medium】【陣列】 && 劍指Offer 面試題3 題目2:不修改陣列找出重複的數字
阿新 • • 發佈:2018-11-10
這道題leetcode和劍指Offer題目略有不同。leetcode說陣列中的重複數可能不止一個,但是結果要求返回一個就行;劍指Offer上說只有一個重複的數,但是重複的次數不一定。兩個題目的共性就是隻需要返回一個重複的數即可。
leetcode 題目:
給定一個包含 n + 1 個整數的陣列 nums,其數字都在 1 到 n 之間(包括 1 和 n),可知至少存在一個重複的整數。假設只有一個重複的整數,找出這個重複的數。
示例 1:
輸入:[1,3,4,2,2]
輸出: 2
示例 2:
輸入: [3,1,3,4,2] 輸出: 3
說明:
- 不能更改原陣列(假設陣列是隻讀的)。
- 只能使用額外的 O(1) 的空間。
- 時間複雜度小於 O(n2) 。
- 陣列中只有一個重複的數字,但它可能不止重複出現一次。
思路:
由於不能使用額外的空間,不能使用記錄或統計出現的數,又不能破壞陣列結構,不能通過排序來判斷相鄰數是否相等。
1.暴力法,兩層迴圈,時間複雜度O(n2)太高。
2.用集合儲存遍歷值,時間複雜度n,但有額外空間開銷。
3.歸併排序,時間複雜度nlogn,空間複雜度 O(1),但破壞陣列結果。
4.二分法,因為數出現在[1,n]。所以統計[1-n/2]的數,如果出現小於等於n/2的數個數超過n/2,[1-n/2]數中有重複的數,繼續通過二分減少搜尋範圍,這裡的時間複雜度為nlogn。
程式碼:
class Solution: def findDuplicate(self, nums): """ :type nums: List[int] :rtype: int """ low,high = 1,len(nums) while low < high: count = 0 mid = (low + high)//2 for item in nums: if item <= mid: count += 1 if count > mid: high = mid else: low = mid + 1 return low