陣列與圖論綜合應用題 Find the Duplicate Number_Leetcode #287

閱讀時間約 3 分鐘
raw-image

這題的題目在這裡:

題目會給我們一個輸入陣列,長度為n+1。

陣列裡面會有n+1個數字,數字的範圍從1到n

裡面恰好有一個數字重複出現,要求我們找出那個重複的數字

題目要求只能使用常數空間O(1),並且限制不能修改陣列內容。


測試範例:

Example 1:

Input: nums = [1,3,4,2,2]
Output: 2

Example 2:

Input: nums = [3,1,3,4,2]
Output: 3

約束條件:

Follow up:

  • How can we prove that at least one duplicate number must exist in nums?
  • Can you solve the problem in linear runtime complexity?

演算法:

除了使用傳統的雙層搜索之外,

還可以使用圖論中的Cycle detection演算法來尋找重複的數字

若我們把陣列每個位置想成一個節點

陣列內部的值,代表一條邊指向下一個節點的位置。

環路Cycle的起點,就對應到陣列中重複出現的數字

以範例一為例:

Input:
nums = [1,3,4,2,2]

raw-image

重複的數字是2

同時,二號節點,也是圖中環路Cycle的起點位置。


程式碼:

class Solution:
 def findDuplicate(self, nums: List[int]) -> int:
  
  # start hopping from Node_#0
  slow, fast = 0, 0

  # for locating start node of cycle
  check = 0
  
  # Step_#1
  # Cycle detection
  # Let slow jumper and fast jumper meet somewhere in the cycle

  while True:
   
    # slow jumper hops 1 step, while fast jumper hops two steps forward.
   slow = nums[ slow ]
   fast = nums[ nums[fast] ]
   
   if slow == fast:
    break
  

  # Step_#2
  # Locate the start node of cycle (i.e., the duplicate number)
  while True:
   
   slow = nums[ slow ]
   check = nums[ check ]
   
   if slow == check:
    break
  
  return check

時間複雜度:

O(n) 整個陣列掃描至多兩遍

空間複雜度:

O(1) 耗費在slow, fast, check等臨時變數上,占用的記憶體空間皆固定O(1),
不會隨著問題規模放大而成長。


Reference:

[1] Python/JS/Java/Go/C++ O(1) aux space by hopping. [ w/ Hint ] — Find the Duplicate Number — LeetCode

52會員
339內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
留言0
查看全部
發表第一個留言支持創作者!
你可能也想看
【💊 Python的解憂錦囊】ArgumentParser 布林與陣列的處理技巧(boolean/array)您是否苦於網路資訊爆炸嗎? 教學何其多,但卻無法好好選擇的困境呢? 歡迎加入「🔒 阿Han的軟體心法實戰營」, 這裡不給您冗餘的雜訊, 單刀直入直接送您重點, 避開選擇障礙的困境, 讓您獲得業界標準的開發起手式, 成為Top 1的頂尖人才。 我們是不是常常看到一些很厲害的專案, 只要「pip i
Thumbnail
avatar
阿Han
2023-09-13
Go 語言中的動態陣列:深入解析切片👨‍💻簡介 在 Go 語言中,切片(Slice)是一種動態序列的資料結構,能夠方便地存儲和操作多個相同類型的元素。切片相比於陣列,更具有彈性,因為它的大小是可變的,可以根據需要動態增長或縮小。切片在處理集合型資料時非常實用,讓你能夠輕鬆地新增、刪除、修改和操作元素。
Thumbnail
avatar
wang alan
2023-08-25
陣列:Go語言中的數據小倉庫👨‍💻簡介 陣列就像是一個儲存相同類型資料的容器,你可以想像成裝滿了一樣東西的盒子,每個東西都叫做陣列元素。這種類型可以是基本的,像是整數或字串,也可以是你自己定義的型別。不過陣列有個限制,就是大小一旦確定就無法改變。在Go語言裡,陣列的長度也是型別的一部分。
Thumbnail
avatar
wang alan
2023-08-24
瑪娃颱風來襲,外頭一陣風一陣雨一陣烈陽的,不知道你有沒有一處可以好好安頓身心的家。你心目中的「家」是什麼樣子呢?我很喜歡《需要房子嗎?老鼠小姐來設計》最後海莉的生活樣貌,那是一處在針葉林裡,四周有著野菇、大樹圍繞,可以遠眺日出日落的平坦之地,她與夥伴正升火,準備煮食一頓美味的晚餐,他們的家僅僅是一個樸實簡單卻又溫暖的帳篷。
Thumbnail
avatar
春日禾
2023-06-01
20220705 衣索比亞罕貝拉可如蜜&巫荔秋 早晨的感官真的比較強烈 台南陣雨同樣的咖啡, 接近的手法, 五感在早晨比較強烈, 回甘是面對苦難的代償?
Thumbnail
avatar
Esteban
2022-07-05