Reorder List
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}
.
终于调试出来了,考的是链表的操作,要对链表的操作非常清楚,否则也是很难调试的,总会有问题出来。我完成的时候50个accepted左右,提交的有400多。差不多10%多一点的通过率,看来还是有一定难度的了。
我的思路是:
1 计算链表长度
2 计算需要插入前面的元素,然后转置这些元素
3 用中间一个共有的元素作为结束点,循环插入。
不是很优化的算法,不过也accepted了。暂时没有想到更加优化的算法。
下面是程序。
class Solution { public: void reorderList(ListNode *(&head)) { if(head == nullptr || head->next == nullptr || head->next->next == nullptr) return; int n = listCount(head); int r = (n-1)/2; int i = 0; ListNode *pre = head; ListNode *cur = head; while (cur->next) { cur=cur->next; if(i<r) i++; else pre=pre->next; } ListNode *tail; tail = reverseList(pre); ListNode *ph = head; while (ph != pre) { insertBack(ph, tail); } ph->next = nullptr; } void insertBack(ListNode *(&head), ListNode *(&back)) { ListNode *temp = back->next; back->next=head->next; head->next=back; head=back->next; back = temp; } ListNode* reverseList(ListNode *(&head)) { if(head == nullptr || head->next == nullptr) return nullptr; ListNode *pre = head->next; ListNode *cur = head->next->next; ListNode *post; pre->next = head; if(cur == nullptr) return pre; if(cur->next != nullptr) post = cur->next; else { cur->next = pre; return cur; } cur->next = pre; while(post != nullptr) { pre = cur; cur = post; post = post->next; cur->next = pre; } return cur; } int listCount(ListNode *head) { int n = 0; ListNode *ph = head; while (ph!=nullptr) { ph = ph->next; n++; } return n; } };
算法很多都能看明白,但是真正动手又是另外一回事了。
4到5星级难度。
考点:
1 反正链表
2 两链表插入节点
3 找到特定节点
//2014-2-19 update void reorderList(ListNode *head) { int len = getLength(head); if (len < 3) return; int m = (len-1)>>1; ListNode *pre = head->next; ListNode *tail = pre->next; while (--m>0) tail = tail->next; while (tail->next) { pre = pre->next; tail = tail->next; } reverseList(pre); tail = pre->next; pre->next = nullptr; intertwinedList(head, tail); } void intertwinedList(ListNode *&h1, ListNode *h2) { ListNode *h = h1; while (h2) { ListNode *t = h2; h2 = h2->next; t->next = h->next; h->next = t; h = t->next; } } void reverseList(ListNode *&pre) { ListNode *tail = pre->next; while (tail->next) { ListNode *t = tail->next; tail->next = t->next;//错误:tail = t->next t->next = pre->next; pre->next = t; } } int getLength(ListNode *h) { int len = 0; for ( ; h; h = h->next) len++; return len; }
目前的最佳答案:逻辑清晰,代码简练。
//2014-2-20 update void reorderList(ListNode *head) { if (!head || !head->next || !head->next->next) return; ListNode *pre = head->next; ListNode *tail = pre->next; while (tail && tail->next) { pre = pre->next; tail = tail->next->next; } reverseList(pre); tail = pre->next; pre->next = nullptr; intertwinedList(head, tail); } void intertwinedList(ListNode *&h1, ListNode *h2) { ListNode *h = h1; while (h2) { ListNode *t = h2; h2 = h2->next; t->next = h->next; h->next = t; h = t->next; } } void reverseList(ListNode *&pre) { ListNode *tail = pre->next; while (tail->next) { ListNode *t = tail->next; tail->next = t->next;//错误:tail = t->next t->next = pre->next; pre->next = t; } }