ฉันเชื่อว่าฉันคิดว่าสิ่งที่ควรใช้งานได้โดยทั่วไปและมีประสิทธิภาพหากคุณรับประกันว่าจะไม่ซ้ำซ้อน * (อย่างไรก็ตามควรขยายให้ครอบคลุมจำนวนหลุมและจำนวนเต็มใด ๆ )
แนวคิดเบื้องหลังวิธีนี้คล้ายกับ quicksort โดยที่เราพบเดือยและพาร์ติชั่นรอบ ๆ จากนั้นทำการรีไซด์ด้วยรูด้านข้าง หากต้องการดูว่าฝ่ายใดมีรูเราพบว่าตัวเลขต่ำสุดและสูงที่สุดและเปรียบเทียบกับเดือยและจำนวนค่าในด้านนั้น สมมติว่าเดือยคือ 17 และจำนวนขั้นต่ำคือ 11 หากไม่มีรูต้องมี 6 หมายเลข (11, 12, 13, 14, 15, 16, 17, 17) หากมี 5 เรารู้ว่ามีรูอยู่ข้างนั้นและเราสามารถเอาคืนไปหาด้านนั้นได้ ฉันมีปัญหาในการอธิบายอย่างชัดเจนยิ่งกว่านั้นดังนั้นลองมาเป็นตัวอย่าง
15 21 10 13 18 16 22 23 24 20 17 11 25 12 14
หมุน:
10 13 11 12 14 |15| 21 18 16 22 23 24 20 17 25
15 คือเดือยที่ระบุโดยไพพ์ ( ||
) มีตัวเลข 5 ตัวทางด้านซ้ายของเดือยตามที่ควรมี (15 - 10) และ 9 ทางด้านขวาซึ่งควรมี 10 (25 - 15) ดังนั้นเราจึงเอาคืนทางด้านขวา; เราจะทราบว่าขอบเขตก่อนหน้านี้คือ 15 ในกรณีที่หลุมอยู่ติดกับมัน (16)
[15] 18 16 17 20 |21| 22 23 24 25
ตอนนี้มีตัวเลข 4 ตัวทางซ้าย แต่ควรมี 5 (21 - 16) ดังนั้นเราจะเรียกคืนที่นั่นและอีกครั้งเราจะทราบขอบเขตก่อนหน้านี้ (เป็นเครื่องหมายวงเล็บ)
[15] 16 17 |18| 20 [21]
ด้านซ้ายมีตัวเลข 2 ตัวที่ถูกต้อง (18 - 16) แต่ด้านขวามี 1 แทน 2 (20 - 18) ขึ้นอยู่กับเงื่อนไขสิ้นสุดของเราเราสามารถเปรียบเทียบหมายเลข 1 กับทั้งสองด้าน (18, 20) และดูว่า 19 หายไปหรือเรียกคืนอีกครั้ง:
[18] |20| [21]
ด้านซ้ายมีขนาดเป็นศูนย์โดยมีช่องว่างระหว่างเดือย (20) และขอบเขตก่อนหน้า (18) ดังนั้น 19 จึงเป็นรู
*: หากมีข้อมูลซ้ำคุณอาจใช้ชุดแฮชเพื่อลบออกในเวลา O (N) โดยใช้วิธีการทั้งหมด O (N) แต่อาจต้องใช้เวลามากกว่าวิธีอื่น