หาค่ามัธยฐานของอาเรย์ไม่ได้เรียงลำดับใน


45

เพื่อหาค่ามัธยฐานของอาร์เรย์ที่ไม่ได้เรียงลำดับที่เราสามารถทำให้นาทีกองในเวลาสำหรับnองค์ประกอบและจากนั้นเราสามารถแยกหนึ่งโดยหนึ่งn / 2องค์ประกอบที่จะได้รับค่ามัธยฐาน แต่วิธีการนี้จะใช้เวลาO ( n log n )เวลาO(nlogn)nn/2O(nlogn)

เราสามารถทำเช่นเดียวกันโดยวิธีการบางอย่างในเวลา ? ถ้าเราทำได้แล้วได้อย่างไรO(n)



1
@JukkaSuomela ทำไมไม่ทำให้คำตอบนี้เป็นคำตอบที่ง่ายและรวดเร็ว (พร้อมคำอธิบายสั้น ๆ ของอัลกอริธึมแบบใดแบบหนึ่ง)
Raphael

2
หมายเหตุอภิปราย meta ที่เกี่ยวข้อง ; เมื่อมันปรากฏขึ้นการค้นหาเว็บอย่างง่ายจะนำไปสู่คำตอบสำหรับคำถามนี้
Raphael

คำตอบ:


45

นี้เป็นกรณีพิเศษของขั้นตอนวิธีการเลือกที่สามารถหา TH องค์ประกอบที่เล็กของอาร์เรย์กับkเป็นครึ่งหนึ่งของขนาดของอาร์เรย์ที่ มีการนำไปใช้ที่เป็นเชิงเส้นในกรณีที่เลวร้ายที่สุดkk

อัลกอริทึมการเลือกทั่วไป

ครั้งแรกเรามาดูอัลกอริทึมfind-kthที่พบ TH องค์ประกอบที่เล็กของอาร์เรย์:k

find-kth(A, k)
  pivot = random element of A
  (L, R) = split(A, pivot)
  if k = |L|+1, return pivot
  if k ≤ |L|  , return find-kth(L, k)
  if k > |L|+1, return find-kth(R, k-(|L|+1))

ฟังก์ชั่นsplit(A, pivot)ส่งกลับL,Rเช่นว่าองค์ประกอบทั้งหมดในRมากกว่าpivotและLอื่น ๆ ทั้งหมด (ลบหนึ่งที่เกิดขึ้นpivot) จากนั้นทั้งหมดจะทำซ้ำ

O(n)O(n2)

กรณีที่เลวร้ายที่สุดเชิงเส้น: อัลกอริทึมค่ามัธยฐานของค่ามัธยฐาน

เดือยที่ดีกว่าคือค่ามัธยฐานของค่ามัธยฐานของอาร์เรย์ย่อยAขนาด 5 ทั้งหมดโดยใช้การเรียกโพรซีเดอร์บนอาร์เรย์ของค่ามัธยฐานเหล่านี้

find-kth(A, k)
  B = [median(A[1], .., A[5]), median(A[6], .., A[10]), ..]
  pivot = find-kth(B, |B|/2)
  ...

O(n)

โปรดทราบว่าเวลาส่วนใหญ่ที่ใช้การหมุนแบบสุ่มนั้นเร็วกว่า


ขนาดนี้เป็น5มาตรฐานหรือไม่ เกิดอะไรขึ้นถ้าขนาดของ A น้อยกว่า 5
Jayesh

สำหรับการแก้ไข n ใด ๆ ความซับซ้อนนั้นคงที่ยกเว้นว่ามันจะไม่มีที่สิ้นสุด ดังนั้นคุณสามารถใช้อัลกอริธึมที่ใช้ได้กับความซับซ้อนอัน จำกัด สำหรับกรณีพิเศษเช่นนั้นแม้ว่ามันจะเป็น O (2 ^ n) สำหรับการแก้ไข n (นั่นคือมากที่สุด 4 ในกรณี) ความซับซ้อนมากที่สุด O (2 ^ 4) = O (1)
v6ak

3
ในอัลกอริทึมแรก: return A[k]ไม่ถูกต้อง (ยกเว้นว่าAเรียงไว้ซึ่งจะทำให้ขั้นตอนวิธีพิจารณา) หากsplitเกิดขึ้นเพื่อแบ่งAเช่นที่k = |L| + 1คุณยังไม่ทราบว่าkองค์ประกอบที่เป็น กรณีพื้นฐานของคุณคือเมื่อ|A| = 1อื่นคุณยังต้องทำการโทรซ้ำหนึ่งในสองสาย
wcochran

2
@NickCaplinger แก้ไขโดยใช้ web.archive.org
jmad

1
ไม่ใช่กรณีที่แย่ที่สุดสำหรับอัลกอริทึมการเลือกทั่วไป O (NlogN) ใช่ไหม แม้ว่าการเรียกซ้ำจะเหลือเพียง 10% ของอาเรย์หลังจากการโทรแต่ละครั้งก็ยังคงเป็นลอการิทึมในพื้นฐานที่ 10
octavian

6

n1/4O(n)

แนวคิดหลักของอัลกอริทึมคือการใช้การสุ่มตัวอย่าง เราต้องหาองค์ประกอบสองอย่างที่อยู่ติดกันในลำดับที่เรียงของอาร์เรย์และที่มีค่ามัธยฐานอยู่ระหว่างพวกเขา ดูข้อมูลอ้างอิง [MU2017] สำหรับการสนทนาที่สมบูรณ์


[MU2017] Michael Mitzenmacher และ Eli Upfal "ความน่าจะเป็นและการคำนวณ: เทคนิคการสุ่มและความน่าจะเป็นในขั้นตอนวิธีและการวิเคราะห์ข้อมูล" บทที่ 3 หน้า 57-62 Cambridge University Press, รุ่นที่สอง, 2017

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.