leetcode day5 -- Reorder List Linked List Cycle II
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}.
分析:翻轉鏈表是很常見的題目,這種翻轉是第一次見。一開始的想法是雙指針法,頭一個指針,尾一個指針,進行合并,但是鏈表是單向的,尾指針不能前移,此種方法不行。然后想到先找到中間結點,將中間結點后部分鏈表翻轉,再進行兩個鏈表的交叉合并,此種方法可行。
代碼如下:
class Solution { public:void reorderList(ListNode *head) {if(!head){return;}ListNode* midNode = findMidNode(head);ListNode* postListHead = midNode->next;midNode->next = NULL;postListHead = reverseList(postListHead);crossMergeList(head,postListHead);} private:ListNode* findMidNode(ListNode *head){if(!head){return NULL;}ListNode* pNode1 = head;ListNode* pNode2 = head->next;if(!pNode2){return pNode1;}else{pNode2 = pNode2->next;}while(pNode2!=NULL){pNode2 = pNode2->next;if(pNode2!=NULL){pNode2 = pNode2->next;}pNode1 = pNode1->next;}return pNode1;}ListNode* reverseList(ListNode* head){ListNode* preNode = NULL;ListNode* curNode = head;while(curNode!=NULL){ListNode* tempNode = curNode->next;curNode->next = preNode;preNode = curNode;curNode = tempNode;}return preNode;}//將頭指針為head2的鏈表交叉連接在頭指針為head1的后面void crossMergeList(ListNode* head1,ListNode* head2){ListNode* tempNode1 = head1;ListNode* tempNode2 = head2;while(head1!=NULL && head2!=NULL){tempNode1 = head1->next;tempNode2 = head2->next;head1->next = head2;head2->next = tempNode1;head1 = tempNode1;head2 = tempNode2;}} };2、Linked List Cycle II
Given a linked list, return the node where the cycle begins. If there is no cycle, return?null.
Follow up:
Can you solve it without using extra space?
分析:乍看是一個很常見的和鏈表中環有關系的題目,但是細想很難,很容易使用雙指針法判斷鏈表是否有環和環的大小,但是要求環的起始點,卻不好想。參考:
http://blog.csdn.net/sysucph/article/details/15378043,大致思路是:首先利用雙指針法,一個指針一次走一步,一個指針一次走兩步,如果有環,兩個指針會相遇,如果沒有則不會相遇。如果相遇此時,將一個指針置于鏈表頭,另一個指針在相遇點,兩個指針每次都走一步,直到兩個指針相遇,此時結點為環的起點。
至于為什么這樣就是環的起點呢,我簡要證明了一下。
代碼如下:
class Solution { public:ListNode *detectCycle(ListNode *head) {if(!head){return NULL;}ListNode* pNode1 = head;ListNode* pNode2 = head;ListNode* firstMeetNode = NULL;while(pNode2!=NULL){pNode1 = pNode1->next;pNode2 = pNode2->next;if(pNode2 != NULL){pNode2 = pNode2->next;}if(pNode1!=NULL && pNode1 == pNode2) {firstMeetNode = pNode2;break;}}if(!firstMeetNode){return NULL;}else{pNode1 = head;while(pNode1 != pNode2){pNode2 = pNode2->next;pNode1 = pNode1->next;}return pNode1;}} };3、Linked List Cycle?
Given a linked list, determine if it has a cycle in it.
Follow up:Can you solve it without using extra space?
分析:做完上一題這一題就很簡單了,就是要注意兩個指針的初始值和后續判斷問題。
代碼如下:
class Solution { public:bool hasCycle(ListNode *head) {if(!head){return NULL;}ListNode* pNode1 = head;ListNode* pNode2 = head;while(pNode2!=NULL){pNode1 = pNode1->next;pNode2 = pNode2->next;if(pNode2 != NULL){pNode2 = pNode2->next;}if(pNode1 != NULL && pNode1 == pNode2){return true;}}return false;} };總結
以上是生活随笔為你收集整理的leetcode day5 -- Reorder List Linked List Cycle II的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: leetcode day2 -- Sor
- 下一篇: leetcode -day8 Copy