เริ่มต้นด้วยสมมติว่าเรากำลังใช้กำลังสอง
1 2 3
2 3 4
3 4 5
1. ค้นหาสี่เหลี่ยม
ฉันจะใช้การค้นหาไบนารีบนเส้นทแยงมุม เป้าหมายคือค้นหาจำนวนที่น้อยกว่าซึ่งไม่ต่ำกว่าจำนวนเป้าหมายอย่างเคร่งครัด
บอกว่าฉันกำลังมองหา4
เช่นนั้นฉันจะสิ้นสุดตำแหน่งที่5
(2,2)
จากนั้นผมมั่นใจว่าถ้า4
เป็นในตารางมันอยู่ที่ตำแหน่งใด(x,2)
หรือ(2,x)
มีในx
[0,2]
นั่นเป็นเพียงการค้นหาไบนารี 2 รายการ
ความซับซ้อนไม่น่ากลัว: O(log(N))
(3 การค้นหาไบนารีในช่วงของความยาวN
)
2. ค้นหารูปสี่เหลี่ยมผืนผ้าวิธีไร้เดียงสา
แน่นอนว่ามันจะซับซ้อนขึ้นเล็กน้อยเมื่อN
และM
แตกต่างกัน (ด้วยรูปสี่เหลี่ยมผืนผ้า) ให้พิจารณากรณีที่เสื่อมถอยนี้:
1 2 3 4 5 6 7 8
2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17
และสมมติว่าฉันกำลังมองหา9
... แนวทแยงมุมก็ยังดี แต่นิยามของเส้นทแยงมุมเปลี่ยนไป [1, (5 or 6), 17]
นี่คือเส้นทแยงมุมของฉันคือ สมมติว่าฉันหยิบขึ้นมา[1,5,17]
แล้วฉันรู้ว่าถ้า9
อยู่ในตารางมันอยู่ในส่วนย่อย:
5 6 7 8
6 7 8 9
10 11 12 13 14 15 16
สิ่งนี้ทำให้เรามีรูปสี่เหลี่ยม 2 รูป:
5 6 7 8 10 11 12 13 14 15 16
6 7 8 9
เพื่อให้เราสามารถเรียกคืนได้! อาจเริ่มต้นด้วยองค์ประกอบที่มีองค์ประกอบน้อยกว่า (แม้ว่าในกรณีนี้มันจะฆ่าเรา)
ฉันควรชี้ว่าหากมิติใดมิติหนึ่งน้อยกว่า3
เราไม่สามารถใช้วิธีการเส้นทแยงมุมได้และต้องใช้การค้นหาแบบไบนารี ในที่นี้จะหมายถึง:
- ใช้การค้นหาแบบไบนารีบน
10 11 12 13 14 15 16
ไม่พบ
- ใช้การค้นหาแบบไบนารีบน
5 6 7 8
ไม่พบ
- ใช้การค้นหาแบบไบนารีบน
6 7 8 9
ไม่พบ
มันยุ่งยากเพราะเพื่อให้ได้ประสิทธิภาพที่ดีคุณอาจต้องการแยกความแตกต่างระหว่างหลาย ๆ กรณีขึ้นอยู่กับรูปร่างทั่วไป ....
3. ค้นหารูปสี่เหลี่ยมผืนผ้าวิธีการที่โหดร้าย
มันจะง่ายกว่ามากถ้าเราจัดการกับสี่เหลี่ยม ...
1 2 3 4 5 6 7 8
2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17
17 . . . . . . 17
. .
. .
. .
17 . . . . . . 17
ตอนนี้เรามีสี่เหลี่ยม
แน่นอนว่าเราอาจจะไม่สร้างแถวเหล่านั้นจริงๆเราสามารถจำลองแถวเหล่านั้นได้
def get(x,y):
if x < N and y < M: return table[x][y]
else: return table[N-1][M-1] # the max
ดังนั้นมันจึงทำงานเหมือนสี่เหลี่ยมโดยไม่ต้องใช้หน่วยความจำมากขึ้น (ในราคาความเร็วอาจขึ้นอยู่กับแคช ... โอ้ดี: p)
[[1 1][1 1]]
?