Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder 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}
.
这一题涉及到了 单链表的中点查找、部分反序、合并 三种操作。
搞了很久,头晕。
1.查找采用的是两倍距离方法,两个指针采用步长差2倍的方式向后移动。这个方法在链表的遍历中,很受用。链表于数组不同,没有索引,所以要定位到某一个节点,必须要经过遍历。于计算总长度,然后再按照位置查找来说,次方法很高效。
2.反序采用三个指针辅助完成。
3.合并:略过。
/******* step 1: finding the middle node step 2: reverse the the latter half step 3: merge two part */ void reorderList(ListNode* head) { if (head == NULL || head -> next == NULL) { return ; } ListNode *p1, *p2, *p3, *head2; p1 = head; p2 = p1 -> next; while (p2 && p2 -> next) { p1 = p1 -> next; p2 = p2 -> next -> next; } head2 = p1 -> next; p1 -> next = NULL; // above code find head2 node which is the mid node p2 = head2 -> next; head2 -> next = NULL; while (p2) { p1 = p2 -> next; p2 -> next = head2; head2 = p2; p2 = p1; } // above code reverse the half part and head2 is the end node for (p1 = head, p2 =head2; p1; ) { auto tmp = p1 -> next; p1 = p1 -> next = p2; p2 = tmp; }
// above code merge the two part to one }