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

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

ในปัญหาอาร์เรย์นี้ เราจะพูดถึงวิธีย้ายองค์ประกอบเชิงลบทั้งหมดไปยังจุดสิ้นสุดหรือจุดเริ่มต้นของอาร์เรย์โดยใช้แนวทางและอัลกอริทึมง่ายๆ

โปรดทราบว่า ลำดับขององค์ประกอบไม่เกี่ยวข้องกับปัญหานี้ เรากำลังพิจารณาเฉพาะองค์ประกอบเชิงลบและวางไว้ที่จุดเริ่มต้นหรือจุดสิ้นสุดของรายการ

วิธีใดที่จะย้ายองค์ประกอบเชิงลบทั้งหมดไปยังด้านหนึ่งของอาร์เรย์

อาร์เรย์ในการเขียนโปรแกรมเป็นหนึ่งในโครงสร้างข้อมูลที่หลากหลายที่สุด นี่เป็นเพราะข้อเท็จจริงที่ว่า จากตัวเลขเป็นจำนวนเต็ม อาร์เรย์อำนวยความสะดวกในการจัดเก็บจำนวนเต็มค่าบวก ค่าลบ และแม้แต่ศูนย์เช่นกัน นอกจากนี้ องค์ประกอบเหล่านี้ภายในอาร์เรย์อาจถูกจัดเก็บไว้ในตำแหน่งสุ่มโดยไม่คำนึงถึงลำดับทั่วไป

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

ปัญหานี้มักถูกถามในการสัมภาษณ์การเขียนโปรแกรม ในส่วนถัดไปของบล็อก เราจะพูดถึงวิธีการเหล่านี้เพื่อ ย้ายองค์ประกอบเชิงลบทั้งหมดไปยังจุดสิ้นสุด ของอาร์เรย์

วิธีย้ายองค์ประกอบทั้งหมดไปด้านหนึ่งในอาร์เรย์ ใช้ซี?

เพื่อเรียนรู้วิธี ย้ายองค์ประกอบเชิงลบทั้งหมดไปยังจุดสิ้นสุด ของอาร์เรย์ เราจะพิจารณาปัญหานี้ด้วยความช่วยเหลือของตัวอย่าง ที่นี่เรามีอาร์เรย์อินพุตที่ประกอบด้วยจำนวนเต็มลบและจำนวนเต็มบวก

ให้เราหารือเกี่ยวกับแนวทางและวิธีการย้ายองค์ประกอบเชิงลบไปยังด้านหนึ่งของอาร์เรย์เพิ่มเติมในส่วนนี้

อินพุตอาร์เรย์

1-2 3-1 8 9

Output Array

1 9 3 8-2-1

ดังที่เราเห็นในเอาต์พุตของ Array องค์ประกอบเชิงลบมี ถูกจัดเรียงไว้ที่ส่วนท้ายของลำดับ

โปรดทราบว่าการจัดเรียงองค์ประกอบเหล่านี้ไม่จำเป็นต้องอยู่ในลำดับที่สมบูรณ์แบบ สามารถจัดเรียงตามลำดับแบบสุ่มได้ตราบเท่าที่เราย้ายองค์ประกอบเชิงลบทั้งหมดให้สิ้นสุด ภายในโปรแกรม

ตอนนี้ ให้เราหารือเกี่ยวกับแนวทางต่างๆ ที่สามารถนำไปใช้ในการเลื่อน องค์ประกอบเชิงลบทั้งหมดในตอนท้ายของอาร์เรย์

วิธีที่ 1: ใช้วิธีไร้เดียงสา

เราจะเริ่มต้นด้วยการพยายามแก้ปัญหานี้โดยใช้วิธีการไร้เดียงสา วิธีนี้ยังเรียกกันทั่วไปว่าเป็นอัลกอริทึมแบบวนซ้ำที่ใช้สำหรับแก้ปัญหาการเขียนโปรแกรมอื่นๆ เช่น การดำเนินการ ซิกแซกเคลื่อนที่ผ่านไบนารีทรี

ในบริบทของการย้ายองค์ประกอบเชิงลบทั้งหมดไปยังจุดสิ้นสุดของอาร์เรย์ เราสามารถ เริ่มต้นด้วยการจัดเรียงอาร์เรย์ที่กำหนดโดยเรียงลำดับจากมากไปน้อย  ด้วยวิธีนี้ องค์ประกอบเชิงลบทั้งหมดจะรวมกันอยู่ที่ส่วนท้ายของอาร์เรย์ เพื่อให้บรรลุเป้าหมายนี้ เราสามารถใช้ฟังก์ชันการเรียงลำดับการเลือก เช่น การเรียงลำดับการเลือก (int arr[], int n) ใน ฟังก์ชันนี้ สำหรับแต่ละองค์ประกอบที่ ith ภายในอาร์เรย์ เราจะพยายามหาองค์ประกอบขั้นต่ำภายใน subarray จาก i+1 และพยายามสลับค่าเพื่อจัดเรียงอาร์เรย์ที่ส่วนท้าย

Time Complexity สำหรับแนวทางนี้:

O(n*log(n))

วิธีที่ 2: การใช้ Partition Approach

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

วิธีง่ายๆ ในการใช้วิธีแบ่งพาร์ติชันคือการใช้การวนซ้ำที่ซ้อนกันสำหรับความยาวทั้งหมดของอาร์เรย์ และการวนรอบนี้จะช่วยเราในการตรวจจับจำนวนเต็มลบที่ต้องย้ายไปยังจุดสิ้นสุด

นี่คือวิธีที่สามารถนำวิธีนี้ไปใช้ได้:

คุณสามารถเริ่มต้นด้วยการประกาศตัวแปร เช่น j=0 ที่จุดเริ่มต้นของอาร์เรย์สำหรับ arr[j] ถัดไป เราจะวนซ้ำข้อมูลทั้งหมดโดยใช้ตัวชี้ i ของลูป ตอนนี้ ในแต่ละขั้นตอนของการวนซ้ำ เราจะเก็บแท็บของข้อเท็จจริงที่ว่า arr[i ] เป็นลบหรือไม่ หากพบว่าเป็นจริง เราจะเปลี่ยนองค์ประกอบด้วย arr[j] และวางไว้ที่จุดเริ่มต้นของอาร์เรย์อินพุตของเรา สุดท้าย คุณสามารถเพิ่มองค์ประกอบ j และค่าของมัน และดำเนินกระบวนการนี้ต่อไป สำหรับองค์ประกอบที่เหลือของอาร์เรย์

ความซับซ้อนของเวลาสำหรับแนวทางนี้:

O(n) 

ในที่นี้ เราได้ถือว่า”n”เป็น เป็นความยาวของอาร์เรย์อินพุตของเรา

วิธีที่ 3: การใช้เทคนิคตัวแปรหรือพอยน์เตอร์

อย่างที่คุณอาจเดาได้ เพื่อที่จะ ย้ายองค์ประกอบเชิงลบทั้งหมดไปจนสุด สำหรับแนวทางที่สาม เราจะเริ่มต้นตัวแปรหรือพอยน์เตอร์สองตัว”m”และ”n”ที่ตำแหน่งเริ่มต้นและสิ้นสุดของอาร์เรย์อินพุต

โดยใช้เทคนิคนี้ เราจะเก็บ ติดตามองค์ประกอบทั้งหมดภายในอาร์เรย์และเพิ่มตัวชี้ m และลดตัวชี้ n ติดต่อกัน

วิธีการทำงานของอัลกอริทึมสำหรับวิธีการนี้:

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

มีปัญหาตามอาร์เรย์มากมายที่สามารถแก้ไขได้โดยใช้พอยน์เตอร์และแนวทางไร้เดียงสา เช่น การดำเนินการซิกแซกผ่าน Binary Tree

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

By Henry Taylor

ฉันทำงานเป็นนักพัฒนาส่วนหลัง พวกคุณบางคนอาจเคยเห็นฉันที่การประชุมนักพัฒนาซอฟต์แวร์ เมื่อเร็ว ๆ นี้ฉันได้ทำงานในโครงการโอเพ่นซอร์ส