ฉันคิดถึงวิธีการแบ่งและพิชิตที่อาจใช้การได้
ก่อนอื่นในการประมวลผลล่วงหน้าคุณต้องใส่ตัวเลขทั้งหมดน้อยกว่าครึ่งหนึ่งของขนาดอินพุต ( n / 3) ลงในรายการ
รับสาย: 0000010101000100
(โปรดทราบว่าตัวอย่างนี้ถูกต้อง)
แทรกช่วงเวลาทั้งหมด (และ 1) จาก 1 ถึง (16/2) ลงในรายการ: {1, 2, 3, 4, 5, 6, 7}
จากนั้นแบ่งครึ่ง:
100000101 01000100
ทำสิ่งนี้ต่อไปจนกว่าคุณจะไปถึงสตริงที่มีขนาด 1 สำหรับสตริงที่มีขนาดหนึ่งด้วย 1 ทั้งหมดให้เพิ่มดัชนีของสตริงลงในรายการของความเป็นไปได้ มิฉะนั้นส่งคืน -1 สำหรับความล้มเหลว
นอกจากนี้คุณจะต้องส่งคืนรายการระยะห่างที่เป็นไปได้ซึ่งเกี่ยวข้องกับดัชนีเริ่มต้นแต่ละรายการ (เริ่มต้นด้วยรายการที่คุณทำด้านบนและลบหมายเลขตามที่คุณไป) ที่นี่รายการที่ว่างเปล่าหมายความว่าคุณกำลังติดต่อกับ 1 คนเดียวเท่านั้นดังนั้นระยะห่างใด ๆ จึงเป็นไปได้ มิฉะนั้นรายการจะรวมถึงการเว้นระยะที่ต้องตัดออก
ดังนั้นดำเนินการตามตัวอย่างด้านบน:
1000 0101 0100 0100
10 00 01 01 01 00 01 00
1 0 0 0 0 1 0 1 0 1 0 0 0 1 0 0
ในขั้นตอนการรวมกันครั้งแรกเรามีแปดชุดสองตอนนี้ ในตอนแรกเรามีความเป็นไปได้ของเซต แต่เราเรียนรู้ว่าการเว้นวรรค 1 นั้นเป็นไปไม่ได้เพราะศูนย์อื่นอยู่ที่นั่น ดังนั้นเราจึงคืนค่า 0 (สำหรับดัชนี) และ {2,3,4,5,7} เนื่องจากข้อเท็จจริงที่ว่าการเว้นวรรคด้วย 1 เป็นไปไม่ได้ ในวินาทีเราไม่มีอะไรเลยและส่งคืน -1 ในสามเรามีการแข่งขันโดยไม่มีการเว้นระยะห่างในดัชนี 5 ดังนั้นกลับ 5, {1,2,3,4,5,7} ในคู่ที่สี่เราคืนค่า 7, {1,2,3,4,5,7} ในวันที่ห้าส่งคืน 9, {1,2,3,4,5,7} ในวันที่หกส่งคืน -1 ในวันที่เจ็ดส่งคืน 13, {1,2,3,4,5,7} ในแปดกลับ -1
เมื่อรวมกันอีกครั้งเป็นสี่ชุดเรามี:
1000
: Return (0, {4,5,6,7})
0101
: Return (5, {2,3,4,5,6,7}), (7, {1,2,3,4,5,6 , 7})
0100
: Return (9, {3,4,5,6,7})
0100
: Return (13, {3,4,5,6,7})
รวมกันเป็นชุดแปด:
10000101
: ส่งคืน (0, {5,7}), (5, {2,3,4,5,6,7}), (7, {1,2,3,4,5,6,7})
01000100
: ส่งคืน (9, {4,7}), (13, {3,4,5,6,7})
รวมกันเป็นชุดสิบหก:
10000101 01000100
ในขณะที่เราก้าวหน้าไปเรายังคงตรวจสอบความเป็นไปได้ทั้งหมด จนถึงขั้นตอนนี้เราได้ทิ้งสิ่งที่เกินกว่าจุดสิ้นสุดของสตริง แต่ตอนนี้เราสามารถตรวจสอบความเป็นไปได้ทั้งหมด
โดยทั่วไปเราจะตรวจสอบ 1 รายการแรกด้วยระยะห่างระหว่าง 5 และ 7 และพบว่าพวกเขาไม่เข้าแถวถึง 1 (โปรดทราบว่าการตรวจสอบแต่ละครั้งเป็นค่าคงที่ไม่ใช่เวลาเชิงเส้น) จากนั้นเราจะตรวจสอบรายการที่สอง (ดัชนี 5) ด้วยระยะห่างระหว่าง 2, 3, 4, 5, 6 และ 7 - หรือเราจะหยุดที่ 2 ตั้งแต่ ที่ตรงกันจริง ๆ
วุ้ย นั่นเป็นอัลกอริทึมที่ค่อนข้างยาว
ฉันไม่รู้ 100% ถ้าเป็นO (n log n)เนื่องจากขั้นตอนสุดท้าย แต่ทุกอย่างจนถึงมีO (n log n)เท่าที่ฉันสามารถบอกได้ ฉันจะกลับไปหาสิ่งนี้ในภายหลังและพยายามปรับขั้นตอนสุดท้าย
แก้ไข: เปลี่ยนคำตอบของฉันเพื่อสะท้อนความคิดเห็นของ Welbog ขออภัยสำหรับข้อผิดพลาด ฉันจะเขียนรหัสเทียมในภายหลังเช่นกันเมื่อฉันมีเวลามากขึ้นในการถอดรหัสสิ่งที่ฉันเขียนอีกครั้ง ;-)