-
Notifications
You must be signed in to change notification settings - Fork 981
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
145 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
举例: | ||
|
||
1->2->3->4->5->6->7->8 | ||
|
||
要求重排为: | ||
|
||
1->8->2->7->3->6->4->5 | ||
|
||
看似摸不着头绪,单链表的最大问题不就是没法走回头路吗? | ||
|
||
但如果我们将链表切成两部分呢? | ||
|
||
1->2->3->4 | ||
5->6->7->8 | ||
|
||
然后回忆一下链表基本操作,咦,是否将第二个链表逆序一下即可? | ||
|
||
1->2->3->4 | ||
8->7->6->5 | ||
|
||
到了这一步,差不多真相大白了吧。两个链表合并,貌似没一点难度。 | ||
|
||
------ | ||
|
||
**具体技术** | ||
|
||
逆序的技巧不需多说,切成两部分,关键是找中点,这个可以利用我们常用的技巧:快慢指针。 | ||
|
||
1->2->3->4->5->6->7->8->null | ||
^ ^ ^ ^ ^ ^ ^ ^ ^ | ||
s f | | | | | | | | ||
s | f | | | | | | | ||
s | f | | | | | | ||
s | | f | | | | | ||
s | f | | | | ||
s | f | | | ||
s f | | ||
s f | ||
|
||
可以看到,`s` 正好停在指向 `4` 的地方。 | ||
|
||
逆序之后,链表应呈现以下情形: | ||
|
||
1->2->3->4->8->7->6->5->null | ||
^ ^ | ||
head slow | ||
|
||
再进一步,将该链表分为两个: | ||
|
||
1->2->3->4->null | ||
8->7->6->5->null | ||
|
||
然后用咱们现成的 `shuffleMerge` 即可。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#include "solution.h" | ||
#include <iostream> | ||
#include <initializer_list> | ||
using namespace std; | ||
|
||
ListNode *create_linkedlist(std::initializer_list<int> lst) | ||
{ | ||
auto iter = lst.begin(); | ||
ListNode *head = lst.size() ? new ListNode(*iter++) : nullptr; | ||
for (ListNode *cur=head; iter != lst.end(); cur=cur->next) | ||
cur->next = new ListNode(*iter++); | ||
return head; | ||
} | ||
|
||
void clear(ListNode *head) | ||
{ | ||
while (head) { | ||
ListNode *del = head; | ||
head = head->next; | ||
delete del; | ||
} | ||
} | ||
|
||
void printList(ListNode *head) { | ||
for (ListNode *cur = head; cur; cur = cur->next) | ||
cout << cur->val << "->"; | ||
cout << "\b\b " << endl; | ||
} | ||
|
||
int main() | ||
{ | ||
Solution s; | ||
ListNode *a = create_linkedlist({1,2,3,4,5,6,7,8,9}); | ||
s.reorderList(a); | ||
printList(a); | ||
clear(a); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#include <cstddef> | ||
|
||
struct ListNode { | ||
int val; | ||
ListNode *next; | ||
ListNode(int x) : val(x), next(NULL) {} | ||
}; | ||
|
||
class Solution { | ||
ListNode* reverseList(ListNode *head) { | ||
ListNode *newHead = NULL; | ||
while (head) { | ||
ListNode *next = head->next; | ||
head->next = newHead; | ||
newHead = head; | ||
head = next; | ||
} | ||
return newHead; | ||
} | ||
|
||
ListNode *shuffleMerge(ListNode *a, ListNode *b) { | ||
ListNode *ret = NULL, **lastRef = &ret; | ||
while (a && b) { | ||
moveNode(lastRef, &a); | ||
lastRef = &((*lastRef)->next); | ||
moveNode(lastRef, &b); | ||
lastRef = &((*lastRef)->next); | ||
} | ||
*lastRef = a ? a : b; | ||
return ret; | ||
} | ||
|
||
void moveNode(ListNode **destRef, ListNode **sourceRef) { | ||
ListNode *newNode = *sourceRef; | ||
*sourceRef = newNode->next; | ||
newNode->next = *destRef; | ||
*destRef = newNode; | ||
} | ||
|
||
public: | ||
void reorderList(ListNode *head) { | ||
if (head == NULL) return; | ||
ListNode *slow = head, *fast = head->next; | ||
while (fast) { | ||
fast = fast->next; | ||
if (fast) { | ||
slow = slow->next; | ||
fast = fast->next; | ||
} | ||
} | ||
ListNode *back = reverseList(slow->next); | ||
slow->next = NULL; | ||
head = shuffleMerge(head, back); | ||
} | ||
}; |