การย้อนกลับรายการโดยใช้สองคิว


12

คำถามนี้ได้รับแรงบันดาลใจจากคำถามที่มีอยู่เกี่ยวกับว่าสแต็กสามารถจำลองได้โดยใช้สองคิวในเวลาตัดจำหน่ายต่อการดำเนินการสแต็ก คำตอบดูเหมือนจะไม่เป็นที่รู้จัก นี่คือคำถามที่เฉพาะเจาะจงมากขึ้นซึ่งตรงกับกรณีพิเศษที่การดำเนินการ PUSH ทั้งหมดจะดำเนินการก่อนตามด้วยการดำเนินการ POP ทั้งหมด รายการขององค์ประกอบNสามารถย้อนกลับได้อย่างมีประสิทธิภาพโดยใช้สองคิวที่ว่างเปล่าเริ่มแรกได้อย่างไร การดำเนินการทางกฎหมายคือ:O(1)N

  1. จัดวางองค์ประกอบถัดไปจากรายการอินพุต (ไปยังส่วนท้ายของคิวทั้งสอง)
  2. ถอนออกจากองค์ประกอบที่หัวของคิวทั้งสองและจัดคิวอีกครั้ง (ไปที่ส่วนท้ายของคิวทั้งสอง)
  3. ถอนออกจากองค์ประกอบที่ส่วนหัวของคิวอย่างใดอย่างหนึ่งและเพิ่มลงในรายการผลลัพธ์

ถ้ารายการป้อนข้อมูลประกอบด้วยองค์ประกอบวิธีการที่ไม่จำนวนขั้นต่ำของการดำเนินงานที่จำเป็นในการสร้างรายชื่อส่งออกตรงกันข้าม[ N , N - 1 , . . , 2 , 1 ]ประพฤติตน? หลักฐานที่แสดงว่ามันโตเร็วกว่าO ( N )จะน่าสนใจเป็นพิเศษเพราะมันจะช่วยแก้ปัญหาเดิมในแง่ลบได้[1,2,...,N1,N][N,N1,...,2,1]O(N)


Update (15 มกราคม 2011): ปัญหาสามารถแก้ไขได้ในดังที่แสดงในคำตอบที่ส่งและความคิดเห็นของพวกเขา; และขอบเขตล่างของΩ ( N )เป็นเรื่องเล็กน้อย ขอบเขตเหล่านี้สามารถปรับปรุงได้หรือไม่?O(NlogN)Ω(N)


เพื่อชี้แจง: โดย "องค์ประกอบสุดท้ายจากทั้งสองคิว" คุณหมายถึงองค์ประกอบที่ส่วนหัวของคิวหรือไม่
Peter Taylor

@ Peter: ใช่ขอบคุณสำหรับการชี้แจง ฉันแก้ไขคำถามแล้ว
mjqxxxx

ทั้งรายการอินพุตและเอาต์พุตแสดงเป็นสแต็กหรือไม่ ถ้าเป็นเช่นนั้น n op1s (ไปที่คิวเดียวกัน) ตามด้วย n op3s กลับด้านใช่มั้ย ฉันคิดว่าฉันต้องคิดถึงบางสิ่งที่สำคัญ
jbapple

@jbapple: ไม่พวกเขาจะไม่สแต็ค คุณต้องเขียนองค์ประกอบไปยังรายการผลลัพธ์ในลำดับตรงกันข้ามที่อ่านจากรายการอินพุต
mjqxxxx

คำตอบ:


11

ถ้า N คือพลังของสองฉันเชื่อว่าการดำเนินการ O (N log N) เพียงพอสำหรับปัญหาที่ค่อนข้าง จำกัด ซึ่งรายการทั้งหมดเริ่มต้นในหนึ่งในคิวและต้องจบลงในลำดับย้อนกลับในหนึ่งในคิว รายการอินพุตและเอาต์พุต)

ในขั้นตอน O (N) เป็นไปได้ที่จะเริ่มต้นด้วยองค์ประกอบทั้งหมดในหนึ่งคิวเล่น "หนึ่งสำหรับคุณหนึ่งสำหรับฉัน" เพื่อแยกพวกเขาออกเป็นชุดย่อยสลับในคิวอื่น ๆ และจากนั้นเชื่อมพวกเขาทั้งหมดกลับเป็นคิวหนึ่ง ในแง่ของการเป็นตัวแทนไบนารีของตำแหน่งของรายการนี้ดำเนินการหมุน

ในขั้นตอน O (N) มันเป็นไปได้ที่จะดึงคู่ของอิลิเมนต์ออกจากหนึ่งคิวสลับพวกมันจากนั้นนำกลับมาวางกลับคู่ทั้งหมด ในแง่ของการเป็นตัวแทนไบนารีของตำแหน่งของรายการนี้เติมเต็มบิตลำดับต่ำของตำแหน่ง

ด้วยการทำซ้ำ O (log N) คูณการสลับและการสลับแบบคู่เราสามารถเสริมบิตทั้งหมดของการเป็นตัวแทนไบนารีของตำแหน่ง - ซึ่งเป็นสิ่งเดียวกันกับการย้อนกลับรายการ


จากนั้นคุณสามารถแยกรายการลงในการแสดงแบบไบนารีและย้อนกลับทีละชิ้นสำหรับอัลกอริทึม O (n lg n) ฉันคิดว่า
jbapple

ฉันคิดว่าเราสามารถขยายไปยัง N ทั้งหมดโดยใช้ต้นไม้ 2-3 ต้นแทนไบนารี แต่บางทีความคิดของคุณก็ง่ายกว่า แต่คุณจะย้อนกลับแต่ละชิ้นของ O (บันทึก n) ในขั้นตอนรวม O (n บันทึก n) ได้อย่างไร
David Eppstein

เวลาคือ O (ผลรวม (2 ^ i) lg (2 ^ i)) สำหรับ i ตั้งแต่ 0 ถึง [lg n] ซึ่ง Wolfram alpha บอกว่าเป็น O (n lg n): wolframalpha.com/input/?i=sum+ (2 ^ k) + log2 + (2 ^ k) + จาก + 0 + ถึง + log2 + n
jbapple

แน่นอนว่าถ้าคุณสามารถย้อนกลับแต่ละชิ้นในเวลาตามสัดส่วนกับความยาวของมันเท่ากับบันทึกของมันคุณก็ทำเสร็จแล้ว แต่คุณต้องวางชิ้นส่วนไว้ที่ไหนสักแห่งเมื่อคุณกลับรายการแล้วนั่นอาจทำให้ยากที่จะกลับรายการที่เหลือ
David Eppstein

ปัญหา posits "รายการผลลัพธ์" เราเอาพวกมันไปไว้ที่นั่นได้ไหม
jbapple

1

i=0N/21(N2i2)

ให้ชื่อสองคิวที่พร้อมใช้งานเป็นซ้ายและขวา นี่คือแนวคิดพื้นฐานของอัลกอริทึมนี้โดยมีสมมติฐานว่า N คือ:

  1. อ่านค่าจากรายการเริ่มต้นขององค์ประกอบและผลักดันตัวเลขคี่ทั้งหมดลงในคิวด้านซ้ายและแม้กระทั่งตัวเลขลงในคิวที่เหมาะสม
  2. หนึ่งในขั้นตอนกำปั้นวิธีที่เร็วที่สุดในการส่งออกค่าสูงสุดคือการถ่ายโอนองค์ประกอบ N / 2-1 จากคิวด้านขวาไปทางซ้ายหนึ่งและป๊อปอัพค่าสูงสุดจากคิวด้านขวาลงในรายการผลลัพธ์
  3. ตอนนี้เราต้องทำเช่นเดียวกันสำหรับคิวอื่น - ถ่ายโอนองค์ประกอบ N / 2-1 จากคิวซ้ายเข้าสู่ขวาหนึ่งและ pop องค์ประกอบด้านบนจากคิวซ้ายเข้าสู่รายการผลลัพธ์
  4. สลับคิวและทำซ้ำขั้นตอนที่ 2 และ 3 สำหรับ N = N-2

มันง่ายที่จะเห็นว่าอัลกอริทึมควรทำงานอย่างไรกับคี่เอ็น


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