前言
這題是一題把陣列當成類似 linked list 的題目,目標是找到陣列中重複的元素,因它只對陣列進行了兩次循環,而每次循環都是線性時間的運作,時間複雜度可達 O(n)
,這裡有 JAVA 和 Python 的寫法。
題目
Given an array of integers
nums
containingn + 1
integers where each integer is in the range[1, n]
inclusive.
There is only one repeated number innums
, return this repeated number.
You must solve the problem without modifying the arraynums
and uses only constant extra space.
給定一個整數陣列
nums
含有n + 1
個整數,每個整數都在[1, n]
範圍包含裡。nums
中只有一個重複的數字,回傳這個重複的數字。
你必須在不能修改nums
的情況下解決這個問題,而且只能使用常數的記憶體空間。
題目連結:https://leetcode.com/problems/find-the-duplicate-number/
題目限制
1 <= n <= 105
nums.length == n + 1
1 <= nums[i] <= n
All the integers in nums
appear only once except for precisely one integer which appears two or more times.
範例
1 | Input: nums = [1,3,4,2,2] |
1 | Input: nums = [3,1,3,4,2] |
思路&筆記
暴力的解法是利用雙迴圈,找出相等的元素後就是答案,結果超過時間限制 (不採用)
另一種解法,運用 HashSet 方法的特性,找出不能出現的元素
- 循環 nums 陣列,把每個元素添加到 HashSet 中
- 如果發現某個元素已經存在於 HashSet 中,那麼這個元素就是重複的
- 回傳這個元素
第三種解法是使用鏈表的特性,在鏈表內的元素不會有重複,有重複的話會形成一個環
- 把當前的元素,當成下一個元素的 index,變成一個類似 linked list 的鏈表
- 然後設定一組快慢指針,慢指針走一步,快指針走兩步,在鏈表中有重複的元素,快指針會先走到有重複元素的環內,慢指針也會走到有重複元素的環內,這時如果快慢指針都走到相同的元素,代表這個元素就是我們要找的重複的元素
- 例如走過 2 這個元素,後面又再次遇到 2 的時候,代表 2 是重複的元素,然而會形成一個環,在這個有重複元素的還內一直打轉
- 另外設定第三個指針檢查,用意是找出環的頭,無論用慢指針或快指針去和檢查指針比對都行,快慢指針是一樣的元素
while 迴圈從 0 開始走,到 3 的時候已經遇到一個 2 了,繼續走到 4 的時候又遇到一個 2
JAVA 實現
1 | // 暴力的解法是利用雙迴圈,找出相等的元素後就是答案,結果超過時間限制 (不採用) |
Python 實現
使用了和 Java 一樣的邏輯執行,換成 Python 的寫法。
1 | class Solution: |
成績
Language | Runtime | Memory |
---|---|---|
Java | 4ms | 59.49MB |
Python | 520ms | 30.95MB |