ฉันรีเฟรช CS Theory ของฉันและฉันต้องการทราบวิธีระบุความซับซ้อนของอัลกอริทึม O (log n) โดยเฉพาะมีวิธีง่าย ๆ ในการระบุหรือไม่
ฉันรู้ด้วย O (n) คุณมักจะมีวงเดียว; O (n ^ 2) เป็นวงคู่ O (n ^ 3) เป็นสามวงเป็นต้นแล้ว O (log n) เป็นอย่างไร
ฉันรีเฟรช CS Theory ของฉันและฉันต้องการทราบวิธีระบุความซับซ้อนของอัลกอริทึม O (log n) โดยเฉพาะมีวิธีง่าย ๆ ในการระบุหรือไม่
ฉันรู้ด้วย O (n) คุณมักจะมีวงเดียว; O (n ^ 2) เป็นวงคู่ O (n ^ 3) เป็นสามวงเป็นต้นแล้ว O (log n) เป็นอย่างไร
คำตอบ:
ฉันรู้ด้วย O (n) คุณมักจะมีวงเดียว; O (n ^ 2) เป็นวงคู่ O (n ^ 3) เป็นสามวงเป็นต้นแล้ว O (log n) เป็นอย่างไร
คุณกำลังทำผิดอยู่ตรงนี้ คุณกำลังพยายามจดจำว่านิพจน์ใหญ่ -O ใดที่มีโครงสร้างอัลกอริทึมที่กำหนด แต่คุณควรนับจำนวนการดำเนินการที่อัลกอริทึมต้องการและเปรียบเทียบกับขนาดของอินพุต อัลกอริธึมที่วนรอบอินพุตทั้งหมดมีประสิทธิภาพ O (n) เนื่องจากรันลูป n ครั้งไม่ใช่เพราะมีลูปเดียว นี่คือลูปเดียวที่มีประสิทธิภาพ O (บันทึก n):
for (i = 0; i < log2(input.count); i++) {
doSomething(...);
}
ดังนั้นอัลกอริทึมใด ๆ ที่จำนวนของการดำเนินการที่จำเป็นอยู่ในลำดับของลอการิทึมของขนาดของอินพุตคือ O (log n) สิ่งสำคัญที่การวิเคราะห์ big-O บอกคุณว่าเวลาดำเนินการของอัลกอริทึมเปลี่ยนแปลงอย่างไรเมื่อเทียบกับขนาดของอินพุต: ถ้าคุณเพิ่มขนาดของอินพุตเป็นสองเท่าอัลกอริทึมจะใช้เวลาอีก 1 ขั้นตอน (O (log n)) สองขั้นตอนมาก (O (n)) สองเท่าหลายขั้นตอน (O (n ^ 2)) ฯลฯ
มันช่วยให้ทราบได้อย่างไรจากประสบการณ์ว่าอัลกอริทึมที่แบ่งพาร์ติชันอินพุตซ้ำ ๆ มักมี 'log n' เป็นส่วนประกอบของประสิทธิภาพหรือไม่? แน่ใจ แต่อย่ามองหาการแบ่งพาร์ติชันและข้ามไปยังข้อสรุปว่าประสิทธิภาพของอัลกอริทึมคือ O (log n) - อาจเป็นสิ่งที่คล้ายกับ O (n log n) ซึ่งแตกต่างกันมาก
แนวคิดคืออัลกอริธึมคือO(log n)
ถ้าแทนที่จะเลื่อนผ่านโครงสร้าง 1 ต่อ 1 คุณจะแบ่งโครงสร้างเป็นสองส่วนซ้ำแล้วซ้ำอีกและทำการดำเนินการจำนวนคงที่สำหรับแต่ละตัวแยก O(log n)
ค้นหาอัลกอริทึมที่มีพื้นที่คำตอบเรื่อยแยกเป็น ตัวอย่างนี้คือการค้นหาแบบไบนารี่ซึ่งคุณจะต้องแยกอาเรย์ที่มีการสั่งซื้อออกเป็นสองส่วนซ้ำแล้วซ้ำอีกจนกว่าคุณจะพบตัวเลข
หมายเหตุ: คุณไม่จำเป็นต้องแบ่งเท่า ๆ กัน
log n
การตอบสนองการค้นหาทวิภาคในผู้คน
ตัวอย่างทั่วไปคือตัวอย่างที่จัดการกับการค้นหาแบบไบนารี ยกตัวอย่างเช่นการค้นหาแบบทวิภาคO(log n)
เป็นปกติ
หากคุณมีแผนภูมิการค้นหาแบบไบนารีการค้นหาการแทรกและการลบนั้นมีO(log n)
ความซับซ้อนทั้งหมด
สถานการณ์ใด ๆ ที่คุณแบ่งพาร์ติชันอย่างต่อเนื่องพื้นที่มักจะเกี่ยวข้องกับlog n
องค์ประกอบ นี่คือเหตุผลที่อัลกอริทึมการเรียงลำดับจำนวนมากมีO(nlog n)
ความซับซ้อนเพราะมักจะแบ่งพาร์ติชันชุดและเรียงลำดับตามที่พวกเขาไป
ถ้าคุณต้องการให้มันง่ายเหมือน "single loop -> O (n), double loop -> O (n ^ 2)" มากกว่าคำตอบน่าจะเป็น "Tree -> O (log n)" การสำรวจต้นไม้อย่างแม่นยำมากขึ้นจากรากหนึ่งไปยังอีกใบหนึ่ง (ไม่ใช่ทั้งหมด!) หรือรอบทางอื่น อย่างไรก็ตามสิ่งเหล่านี้ล้วนเป็นเรื่องง่ายเกินไป
คุณต้องการทราบว่ามีวิธีง่าย ๆ ในการระบุว่าอัลกอริทึมเป็น O (log N) หรือไม่
ดี: เพียงแค่เรียกใช้และเวลามัน รันสำหรับอินพุต 1.000, 10.000, 100.000 และหนึ่งล้าน
หากคุณเห็นว่าเวลาทำงาน 3,4,5,6 วินาที (หรือหลาย ๆ อย่าง) คุณสามารถพูดได้อย่างปลอดภัยว่ามันเป็น O (บันทึก N) หากมันเป็นเช่น: 1,10,100,1000 วินาทีก็อาจเป็น O (N) และถ้ามันเป็นเช่น 3,40,500,6000 วินาทีมันก็จะเป็น O (N log N)