การกลับลำดับของคำในอาเรย์ตัวอักษรอย่างมีประสิทธิภาพ
การกลับลำดับของคำในอาเรย์ตัวอักษรเป็นปัญหาคลาสสิคที่ตรวจสอบความเข้าใจของคุณเกี่ยวกับอัลกอริธึมและการจัดการสตริง ไม่ว่าจะเป็นการเตรียมตัวสำหรับสัมภาษณ์หรือลับคมทักษะการเขียนโปรแกรมของคุณ การเชี่ยวชาญในความท้าทายนี้เป็นสิ่งที่คุ้มค่า ในโพสต์นี้ เราจะสำรวจปัญหาในรายละเอียดและแบ่งการแก้ปัญหาที่มีประสิทธิภาพใน C/C++
ปัญหา
ให้พิจารณาอาเรย์ของตัวอักษรที่สร้างเป็นประโยค เรามุ่งหมายที่จะ กลับลำดับของคำ โดยไม่เปลี่ยนแปลงตัวอักษรในแต่ละคำ ตัวอย่างเช่น ถ้าคุณป้อน:
"this is a string"
ผลลัพธ์ควรเป็น:
'string a is this'
ความท้าทายกำหนดว่า การดำเนินการนี้จะต้องทำให้เสร็จใน เวลา O(N) และ พื้นที่ O(1) ซึ่งหมายความว่าคุณไม่สามารถใช้ฟังก์ชันเช่น split()
หรือโครงสร้างข้อมูลอื่นๆ เช่น สแตกที่ใช้พื้นที่เพิ่มเติมได้
การวิเคราะห์ปัญหา
เวลาที่ใช้ในการประมวลผล
ความต้องการสำหรับความซับซ้อนเวลา O(N) หมายความว่า อัลกอริธึมจะต้องทำการวนซ้ำแบบเชิงเส้นผ่านข้อมูล ดังนั้นเราควรหลีกเลี่ยงการใช้ลูปที่ซ้อนกันที่เพิ่มความซับซ้อนไปมากขึ้น
พื้นที่ที่ใช้ในการประมวลผล
สำหรับความซับซ้อนพื้นที่ O(1) เราไม่สามารถใช้โครงสร้างข้อมูลเพิ่มเติมเพื่อเก็บข้อมูลได้ ซึ่งหมายความว่าการดำเนินการทั้งหมดจะต้องเกิดขึ้นภายในอาเรย์ที่ใช้เข้ามา
การแก้ปัญหา
เรามาแบ่งการแก้ปัญหาออกเป็นขั้นตอน โดยจะใช้วิธีการวนซ้ำสองครั้งเพื่อแก้ปัญหานี้อย่างมีประสิทธิภาพ
ขั้นตอนที่ 1: การกลับอาเรย์ทั้งหมด
ขั้นตอนแรกคือการกลับอาเรย์ทั้งหมด ซึ่งจะเปลี่ยนสตริงต้นฉบับให้เป็นสตริงที่ตัวอักษรทั้งหมดถูกกลับ ในตัวอย่างของเรา "this is a string"
หลังจากกลับจะเป็น:
"gnirts a si siht"
ขั้นตอนที่ 2: การกลับแต่ละคำ
ตอนนี้เราได้กลับอาเรย์ทั้งหมดแล้ว เราต้องกลับแต่ละคำกลับมาที่ลำดับที่ถูกต้อง นี่คือวิธีการที่เราสามารถดำเนินการเหล่านี้ใน C/C++:
void swap(char* str, int i, int j) {
char t = str[i];
str[i] = str[j];
str[j] = t;
}
void reverse_string(char* str, int length) {
for(int i = 0; i < length / 2; i++) {
swap(str, i, length - i - 1);
}
}
void reverse_words(char* str) {
int l = strlen(str);
// กลับอาเรย์ทั้งหมด
reverse_string(str, strlen(str));
int p = 0;
// หาขอบเขตของคำและกลับคำโดยคำ
for(int i = 0; i < l; i++) {
if(str[i] == ' ') {
reverse_string(&str[p], i - p); // กลับคำที่ระบุ
p = i + 1;
}
}
// สุดท้ายกลับคำสุดท้าย
reverse_string(&str[p], l - p);
}
อธิบายโค้ด
- ฟังก์ชัน Swap: เราใช้ฟังก์ชันช่วย
swap
เพื่อแลกเปลี่ยนตัวอักษรในอาเรย์ - ฟังก์ชัน Reverse String: ฟังก์ชันนี้ทำให้ตัวอักษรในสตริงกลับไปโดยใช้ฟังก์ชัน swap
- ฟังก์ชัน Reverse Words: ฟังก์ชันหลักจะกลับอาเรย์ตัวอักษรทั้งหมดก่อน และจากนั้นทำการวนซ้ำเพื่อต้องกลับแต่ละคำที่จำแนกโดยช่องว่าง คำสุดท้ายจะได้รับการจัดการหลังจากที่ลูปจบลง
การวิเคราะห์ความซับซ้อน
การกลับผ่านอาเรย์ 2 ครั้งทำให้ความซับซ้อนเวลาเป็น O(N):
- การวนรอบครั้งแรก: O(N) สำหรับการกลับทั้งสตริง
- การวนรอบครั้งที่สอง: O(N) สำหรับการกลับแต่ละคำ
ดังนั้น ความซับซ้อนเวลาโดยรวมยังคงเป็น O(N) พื้นที่ที่ใช้คือ O(1) เนื่องจากไม่มีพื้นที่เพิ่มเติมถูกใช้ นอกจากตัวแปรสำหรับการวนซ้ำ
สรุป
การกลับลำดับของคำในอาเรย์ตัวอักษรอย่างมีประสิทธิภาพต้องการการรวมกันของการจัดการสตริงและความเข้าใจในการเข้าถึงแบบดัชนี อัลกอริธึมที่นำเสนอในที่นี้แสดงให้เห็นถึงวิธีการที่ชัดเจนที่ตรงตามข้อกำหนดเวลา O(N) และพื้นที่ O(1) ขณะใช้ C/C++ ฝึกฝนการแก้ปัญหานี้และคุณจะพบว่ามันเป็นเครื่องมือที่ยอดเยี่ยมในการเขียนโปรแกรมของคุณ!