การค้นหาจำนวนองค์ประกอบที่เล็กลงสำหรับแต่ละองค์ประกอบในอาเรย์อย่างมีประสิทธิภาพ


9

ฉันติดอยู่กับปัญหานี้:

รับอาร์เรย์ A ของแรก n ตัวเลขธรรมชาติที่มีการเรียงสับเปลี่ยนแบบสุ่มอาร์เรย์ B ถูกสร้างขึ้นเช่นนั้น B(k) คือจำนวนองค์ประกอบจาก A(1) ถึง A(k1) ซึ่งเล็กกว่า A(k).

ฉัน) ได้รับ A คุณสามารถหา B ใน O(n)เวลา?
ii) ให้ไว้B คุณสามารถหา A ใน O(n) เวลา?

ที่นี่ B(1)=0. สำหรับตัวอย่างที่เป็นรูปธรรม:

|A843172965B000031644|

มีใครช่วยฉันบ้าง ขอบคุณ


ฉันพบสิ่งนี้: การเข้ารหัสการเปลี่ยนแปลงการคำนวณที่ให้O(nlogn)อัลกอริทึมสำหรับปัญหาเหล่านี้ อย่างน้อยฉันคิดว่าพวกเขามีปัญหาเดียวกัน
Realz Slaw

@Merbs คำแนะนำที่คุณให้หมายความว่าคุณมีทางออกหรือไม่?
AJed

1
@Ajed มันหมายความว่าฉันมีอัลกอริทึมแม้ว่ามันจะใช้เวลา O(n2) สำหรับอัลกอริทึมอย่างง่ายที่ไม่มีช่องว่างและ O(nlogn)ถ้าเราได้รับอนุญาตพื้นที่ ในขณะนี้ฉันกำลังโน้มตัวไปหาคนที่ไม่สามารถทำได้O(n)และทั้งคู่เป็นอัลกอริทึมเดียวกัน
Merbs

@Merbs ฉันรู้สึกว่าคำใบ้ของคุณสามารถนำไปสู่เส้นทางที่ถูกต้องได้ ฉันมีหนึ่งวิธีแก้ปัญหาด้วย (ทำตามคำแนะนำของคุณ) ฉันเดาว่ามีเคล็ดลับในการวิเคราะห์ที่เป็นไปได้O(n).. ฉันคิดว่าเคล็ดลับคือความรู้ที่ว่า A ไปจาก 1:nเท่านั้น
AJed

2
บทความนี้ยังให้ O(nlogn)ขั้นตอนวิธี คุณแน่ใจหรือว่ามีO(n)อัลกอริทึมสำหรับสิ่งนี้?
Realz Slaw

คำตอบ:


1

อัลกอริทึมไร้เดียงสาสำหรับการพิจารณา B จาก A:

สำหรับ k=1,,nกำหนดค่าของ B(k) โดยเปรียบเทียบกัน A(i) ถึง A(k) สำหรับ i=1,,k และนับคนที่พอใจ A(i)<A(k).

อัลกอริทึมนี้เปรียบเทียบ A(1) ถึงคนอื่น ๆ (n1 ครั้ง) A(2) ถึง n2 อื่น ๆ เป็นต้นจำนวนการเปรียบเทียบทั้งหมดคือ (n1)(n2)2. แต่นั่นไม่ใช่สิ่งที่ดีที่สุดที่เราทำได้ ตัวอย่างเช่นมองไปที่B(n)เราไม่ต้องทำการเปรียบเทียบใด ๆ ! B(n)=A(n)1เพราะมันเป็นครั้งแรก n ตัวเลขธรรมชาติและมันรับประกัน (โดยไม่คำนึงถึงการเปลี่ยนแปลง) ว่า n1ตัวเลขธรรมชาติที่ต่ำกว่าจะอยู่ที่นั่น เกี่ยวกับอะไรB(n1)? แทนที่จะตรวจสอบA(1) ตลอด A(n2)เราสามารถตรวจสอบได้ A(n). นั่นคือ:

สำหรับ k=1,,n2ใช้อัลกอริทึมด้านบน สำหรับ k=n2,,n ใช้อัลกอริทึมย้อนกลับ: ตรวจสอบ B(k) โดยการตั้งค่าเริ่มต้นเป็น A(n)1 แล้วลบออก 1 สำหรับแต่ละรายการ A(i) สำหรับ i=k+1,,n ที่น้อยกว่า A(k).

สิ่งนี้จะใช้เวลา 2×(n21)(n22)2=(n2)(n4)4 ขั้นตอนซึ่งยังคงอยู่ O(n2). โปรดทราบว่าในการสร้างA จาก Bถ้า B(n)=A(n)1 แล้วก็ A(n)=B(n)+1.

แต่ตอนนี้สำหรับกลเม็ดเด็ดพรายมากขึ้น หากเราอนุญาตพื้นที่เพิ่มเติมหรือเรียงลำดับเราสามารถจัดเรียงตัวเลขเมื่อเราทำการเปรียบเทียบ ตัวอย่างเช่น:

|A843172965S987432165B0000316|

แทนที่จะตรวจสอบทั้งหมด (หรือตรวจสอบตามลำดับ) เราสามารถใช้การค้นหาแบบไบนารี่เพื่อตรวจสอบแต่ละรายการ B(k). อย่างไรก็ตามการเรียงลำดับยังคงต้องใช้เวลาO(nlogn).


นี่เป็นเพียงความคิดแรกของฉัน แม้ว่าฉันจะรู้ว่าปัญหาน่าสนใจมากกว่าที่ฉันเคยให้เครดิต และฉันยังไม่มีโอกาสอ่านผลการวิจัยของ Realz Slaw ดังนั้นอัลกอริทึมอาจจะปิด
Merbs

0

แทนที่จะพิจารณาแต่ละข้อ B(k) ในแต่ละครั้งเราสามารถมองไปข้างหน้าและผ่านแต่ละหมายเลขเท่านั้น A ครั้งเดียว ! แต่เราจะใช้n พื้นที่:

|A123456789B800000000104000011112030001222230101123333407011233345320123444561901234445666012344567450123456784|

เราสามารถประหยัดเวลาได้มากขึ้นโดยไม่อัปเดตผู้ที่ได้รับการพิจารณาแล้ว (นั่นคือไม่มีจุดในการอัปเดต 8 หลังจากขั้นตอนแรก) แต่ในกรณีที่เลวร้ายที่สุดเรายังต้องอัปเดต (n)(n+2)2 ครั้ง


0

ทั้ง I และ II เป็นแก้ปัญหาได้โดยใช้ #next_greater_element ที่ฉันอธิบายที่นี่ แต่มันยากกว่าปัญหาเล็กน้อย แต่ก่อนการแก้ปัญหาคุณจะต้องเรียนรู้องค์ประกอบต่อไปที่ยิ่งใหญ่กว่า:

  1. พิจารณาว่าเรามีเวกเตอร์สำหรับทุกองค์ประกอบของ A ตั้งชื่อมัน Si สำหรับองค์ประกอบ i. ตอนนี้เคยเรียกใช้อัลกอริทึมที่มากขึ้นถัดไปเริ่มต้นจากขวาไปซ้าย แต่ยกเว้นองค์ประกอบการตั้งค่าi ใน A ดัชนีองค์ประกอบที่ยิ่งใหญ่ขึ้นถัดไปของมันผลักดัน Si องค์ประกอบที่ i เป็นองค์ประกอบที่ยิ่งใหญ่ต่อไปของพวกเขาจากนั้นทำซ้ำในอาร์เรย์จากซ้ายไปขวาแล้ว B[i]=j=0x(Si[j]+1) ที่ไหน x คือขนาดของเวกเตอร์ Si.และมัน Θ(n) เพราะอัลกอริทึมที่ยิ่งใหญ่ต่อไปคือ Θ(n) และยังเป็นซ้ำ Θ(n)

ส่วนที่สองก็คล้ายกันสังเกตว่าเราสามารถรับค่าขององค์ประกอบที่ถูกต้องมา O(1) แก้ไข: ทางออกของฉันผิดดูเหมือนว่ามันไม่มีo(n) สารละลาย

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