สมมติว่าเรามีรายการที่เชื่อมโยงเช่น l1 -> l2 -> l3 -> l4 -> … -> l(n-1) -> ln เราต้องจัดเรียงรายการนี้ใหม่ในรูปแบบ l1 -> ln -> l2 -> l(n - 1) -> … และอื่นๆ ข้อจำกัดในที่นี้คือ เราไม่สามารถแก้ไขค่าในโหนดรายการได้ เฉพาะตัวโหนดเท่านั้นที่สามารถเปลี่ยนแปลงได้ ตัวอย่างเช่น หากรายการเป็นแบบ [1,2,3,4,5] ผลลัพธ์จะเป็น [1,5,2,4,3]
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
กำหนดวิธีการที่เรียกว่าย้อนกลับเพื่อดำเนินการย้อนกลับ การดำเนินการนี้จะใช้ส่วนหัวของโหนดและโหนดก่อนหน้า ซึ่งจะทำหน้าที่ดังต่อไปนี้ −
-
ถ้า head เป็น null ให้คืนค่าก่อนหน้า
-
temp :=ถัดไปของหัว
-
ถัดไปของหัว :=ก่อนหน้า และ ก่อนหน้า :=หัว
-
ย้อนกลับ (ชั่วคราว ก่อนหน้า)
-
งานการเรียงลำดับใหม่จะเป็นดังนี้ -
-
ถ้า head เป็น null ก็คืนค่า null
-
กำหนดตัวชี้โหนดสองตัวที่เรียกว่าช้าและเร็ว และเริ่มต้นพวกมันด้วยหัว
-
ในขณะที่ fast และ next of fast ทั้งคู่จะไม่เป็นโมฆะ
-
ช้า :=ถัดจากช้า
-
เร็ว :=ถัดไปของเร็ว
-
-
เร็ว :=ย้อนกลับ (ถัดจากช้า)
-
ตั้งค่าถัดไปของ slow เป็น null และ slow :=head
-
กำหนดตัวชี้โหนดรายการสองตัว temp1 และ temp2
-
ในขณะที่ความรวดเร็วนั้นไม่เป็นโมฆะ
-
temp1 :=ถัดจากช้า temp2 :=ถัดไปอย่างรวดเร็ว
-
ถัดไปจากช้า :=เร็ว ถัดไปอย่างรวดเร็ว :=temp1
-
ช้า :=temp1, เร็ว :=temp2
-
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
#include <bits/stdc++.h> using namespace std; class ListNode{ public: int val; ListNode *next; ListNode(int data){ val = data; next = NULL; } }; ListNode *make_list(vector<int> v){ ListNode *head = new ListNode(v[0]); for(int i = 1; i<v.size(); i++){ ListNode *ptr = head; while(ptr->next != NULL){ ptr = ptr->next; } ptr->next = new ListNode(v[i]); } return head; } void print_list(ListNode *head){ ListNode *ptr = head; cout << "["; while(ptr){ cout << ptr->val << ", "; ptr = ptr->next; } cout << "]" << endl; } class Solution { public: ListNode* successor = NULL; ListNode* reverse(ListNode* head, ListNode* prev = NULL){ if(!head)return prev; ListNode* temp = head->next; head->next = prev; prev = head; return reverse(temp, prev); } void reorderList(ListNode* head) { if(!head)return; ListNode* slow = head; ListNode* fast = head; while(fast && fast->next){ slow = slow->next; fast = fast->next->next; } fast = reverse(slow->next); slow->next = NULL; slow = head; ListNode *temp1, *temp2; while(fast){ temp1 = slow->next; temp2 = fast->next; slow->next = fast; fast->next = temp1; slow = temp1; fast = temp2; } } }; main(){ vector<int> v = {1,2,3,4,5}; ListNode *h1 = make_list(v); Solution ob; (ob.reorderList(h1)); print_list(h1); }
อินพุต
[1,2,3,4,5]
ผลลัพธ์
[1, 5, 2, 4, 3, ]