อัลกอริทึม: ฉันจะรวม O (n) และ O (nlog (n)) เข้าด้วยกันได้อย่างไร


22

ฉันมีอัลกอริทึมติดตามซึ่งพบการซ้ำและลบออก:

public static int numDuplicatesB(int[] arr) {
    Sort.mergesort(arr);
    int numDups = 0;
    for (int i = 1; i < arr.length; i++) {
        if (arr[i] == arr[i - 1]) {
            numDups++;
} }
    return numDups;
}

ฉันกำลังพยายามค้นหาเวลาที่ซับซ้อนที่สุดในกรณีนี้ ฉันรู้ว่าเป็น mergesort nlog(n)และในของฉันสำหรับห่วงฉัน iterating nกว่าชุดข้อมูลทั้งหมดเพื่อที่จะนับเป็น ฉันไม่แน่ใจว่าจะทำอย่างไรกับตัวเลขเหล่านี้ ฉันควรรวมพวกเขาเข้าด้วยกันไหม? ถ้าฉันจะทำอย่างนั้นฉันจะทำอย่างไร


1
หมายเหตุด้านข้าง: คุณสามารถใช้ตารางแฮชเพื่อทำสิ่งนี้ใน O (n) ขึ้นอยู่กับข้อกำหนดของหน่วยความจำ
corsiKa

คำตอบ:


67
O(n) + O(n log(n)) = O(n log(n))

สำหรับความซับซ้อนของ Big O สิ่งที่คุณสนใจคือคำศัพท์ที่โดดเด่น n log(n)ปกครองnเพื่อให้เป็นคำเดียวที่คุณสนใจ


4
อีกวิธีหนึ่งในการคิดเกี่ยวกับสิ่งนี้คือการจินตนาการว่าการประมวลผล O (n) ของคุณคือ O (n log n) จริง ๆ ราวกับว่าคุณทำสองประเภทที่เป็นอิสระ จากนั้นคุณมี 2 * O (n log n) แต่ค่าคงที่จะหลุดออกดังนั้นคุณจะกลับไปที่ O (n log n)
Jonathan Eunice

4
@ โจนาธานในขณะที่มันใช้งานได้จริงมันเป็นความจริงที่ว่า O (n) ไม่เท่ากับ O (n log (n)) ดังนั้นฉันจะไม่แนะนำให้ใช้มันเป็นประจำ
Aza

17
@Emrakul จริง ๆ แล้วฉันคิดว่าการให้เหตุผลเป็นไปในทางทฤษฎีเช่นเดียวกับในทางปฏิบัติ O (n) เป็นชุดย่อยที่เหมาะสมของ O (n log (n)) ดังนั้นถ้า f (n) เป็นของ O (n) มันก็เป็นของ O (n log (n))
emory

17
มันควรจะตั้งข้อสังเกตว่าเมื่อเราพูดสิ่งที่เรากำลังจะบอกว่ามันคือฟังก์ชั่นf(n) is O(g(n)) f is a member of the set of functions that grows at the rate of at most g(n) over the long termซึ่งหมายความว่าสมาชิกทุกคนยังเป็นสมาชิกของO(n) ในการแสดงออกชอบจริงหมายถึงสหภาพชุด (ซึ่งคุณอวดความรู้จริงๆคุณจริงๆควรใช้∪) O(n*log(n))+O(f(n)) + O(g(n))
Lie Ryan

3
@LieRyan แต่เดิมก็ไม่ได้ตั้งสหภาพ A + B = { a + b | a in A, b in B }แต่ผลรวมชุด: มันเกิดขึ้นว่าสำหรับชุดของแบบฟอร์มO(g(n))นี้จะเหมือนกันกับชุดการรวมเป็นหนึ่งในชุดที่มักจะเป็นส่วนย่อยของชุดอื่น ๆ และพวกเขาทั้งสองมีค่าคงที่กับผลรวม (เช่น A + A = A) (อ๊ะเนทเขียนเหมือนเดิม)
Paŭlo Ebermann

56

เหตุผล Let 's Oวิธีการของเราผ่านมันและจำความหมายของ สิ่งที่ฉันจะใช้สำหรับขีด จำกัด ไม่มีที่สิ้นสุด

คุณถูกต้องในการระบุว่าคุณดำเนินการสองอย่างด้วยขอบเขตแบบอะซิมโทติคที่สอดคล้องกันO(n)และO(nlog(n))การรวมพวกมันเข้ากับขอบเขตเดียวนั้นไม่ได้ง่ายเหมือนการเพิ่มทั้งสองฟังก์ชั่น คุณรู้ว่าฟังก์ชั่นของคุณใช้เวลาอย่างน้อยO(n)และอย่างน้อยก็O(nlog(n))เช่นกัน ดังนั้นจริงๆชั้นซับซ้อนสำหรับการทำงานของคุณเป็นสหภาพของO(n)และO(nlog(n))แต่O(nlog(n))เป็นซูเปอร์ดังนั้นจริงๆมันเป็นเพียงO(n)O(nlog(n))


12
+1 นี่คือคำตอบ มันอธิบายคำตอบที่แม่นยำยิ่งขึ้นโดยใช้คำศัพท์ compsci

5

หากคุณกำลังจะกำหนดมันไว้ในระยะยาวมันจะมีลักษณะเช่นนี้:

สมมติว่าเวลาทั้งหมดคือ: + bn log (n) โดยที่ a และ b เป็นค่าคงที่ (ไม่สนใจคำสั่งที่ต่ำกว่า)

ในฐานะที่เป็น n ไปที่อินฟินิตี้ (บันทึก + + bn (n)) / n บันทึก (n) -> a / log (n) + b -> b

ดังนั้นเวลาทั้งหมดคือ O (bn log (n)) = O (n log (n))


2

เริ่มต้นด้วยคำจำกัดความของ O ():

O (n log n) หมายถึง "น้อยกว่า C n log n หาก n มีขนาดใหญ่"

O (n) หมายถึง "น้อยกว่า D n ถ้า n มีขนาดใหญ่"

หากคุณเพิ่มทั้งสองผลลัพธ์จะน้อยกว่า Cn log n + D n <C n log n + D n log n <(C + D) n log n = O (n log n)

โดยทั่วไปหาก f (n)> C g (n) สำหรับ n ขนาดใหญ่และบาง C> 0 ดังนั้น O (f (n)) + O (g (n)) = O (f (n)) และหลังจากทำสองสามกรณีโดยใช้คำจำกัดความของ O () คุณจะรู้ว่าคุณสามารถทำอะไรและไม่สามารถทำได้


1

สัญกรณ์ O ใหญ่ถูกกำหนดเป็นชุด:

ป้อนคำอธิบายรูปภาพที่นี่

ดังนั้นป้อนคำอธิบายรูปภาพที่นี่มีฟังก์ชั่นทั้งหมดที่ - เริ่มต้นจากจุดใหญ่โดยพลการป้อนคำอธิบายรูปภาพที่นี่- เล็กกว่าเสมอ

ตอนนี้เมื่อคุณมีฟังก์ชั่นที่อยู่ในป้อนคำอธิบายรูปภาพที่นี่แล้วดำเนินการอีกอย่างที่เพิ่มขึ้นช้ากว่า g มันเพิ่มขึ้นช้ากว่า 2g แน่นอน ดังนั้นการดำเนินการอะไรที่ช้ากว่า g จะไม่เปลี่ยนคลาสความซับซ้อน

เป็นทางการมากขึ้น:

f, h \ in \ mathcal {O} (g) \ Rightarrow (f + h) \ in \ mathcal {O} (g)

คุณสามารถพิสูจน์ได้อย่างง่ายดาย

TL; DR

ก็ยังคงเป็น ไม่มีบันทึก (n)

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