Given a singly linked list L: L0→L1→…→Ln-1→Ln,
eorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
You must do this in-place without altering the nodes' values.
For example,
Given {1,2,3,4}
, reorder it to {1,4,2,3}
.
解题思路:首先取得整个链表的中间节点;然后,对后半段链表进行逆序排列(首先,把后半段链表的值放到listr中,然后逆序构造链表);最后,通过把前半段和后半短链表元素连接,构造题目要求的链表。
代码:
class Solution { public: void reorderList(ListNode *head) { if(head == NULL){ return; } if(head->next == NULL){ return; } ListNode* mid = middle_node(head); list<int> temp_storage; while(mid != NULL){ temp_storage.push_front(mid->val); mid = mid->next; } list<int>::iterator first = temp_storage.begin(); list<int>::iterator second = temp_storage.end(); ListNode* current = head; vector<ListNode*> mid_list; while(first != second){ ListNode *new_node = new ListNode(*first); mid_list.push_back(new_node); ++first; } ListNode* second_current; int i; for(i=0;i<mid_list.size();i++){ second_current = current->next; current ->next = mid_list[i]; mid_list[i]->next = second_current; current = second_current; } if(second_current->val == mid_list[i-1]->val){ mid_list[i-1]->next = NULL; } else{ second_current->next = NULL; } } ListNode* middle_node(ListNode* x){ ListNode* single_step = x; ListNode* double_step = x; while(double_step != NULL){ single_step = single_step->next; if((double_step = double_step->next) == NULL){ break; } double_step = double_step->next; } return single_step; } };
需要注意的是:
1,如何查找链表的中间节点。定义两个指针,一个慢指针,每次跑一步,一个快指针,每次跑两步。当快指针跑到链表结束的时候,慢指针即到达链表中间节点。(如果是奇数个元素的链表,则正好是中间元素;如果是偶数个元素的链表,如4个元素,则返回的是第3个元素。函数ListNode* middle_node(ListNode* x)( )即实现以上功能。注意循环过程中,快指针走一步的时候需要先判断一下,看是不是到达链表末尾)
2,前半段链表和后半段链表的逆序链表进行重构时,需要注意的是:重构完之后,需要对最后的链表元素进行处理,否则,因为最后的链表元素在原来的链表中有next,所以会导致出错。