Reverse Linked List是典型的链表头插法的实例。头插法比较简单易懂,条理清晰,是做很多linked list题目的关键。首先用最简单的Reverse Linked List这道题举例,简单说明一下什么是头插法。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==nullptr)
return nullptr;
ListNode* dummy=new ListNode(-1);
ListNode* cur=head;
dummy->next=head;
while(head->next!=nullptr){
ListNode* next=head->next->next;
head->next->next=dummy->next;
dummy->next=head->next;
head->next=next;
}
return dummy->next;
}
};
在linked list里面,dummy和head是永远不会变的两个节点。头插法就是不停的将head->next插入到dummy和dummy->next之间,也就是除了dummy之外整个链表的开头。整个过程一共有四步
1.新建一个指针指向要移动的节点的下一个节点
2.移动head的下一个节点的next指针,指向dummy->next
3.dummy指向刚刚插入的节点
4.head指向新的next节点。
对于移动哪一个节点,改变哪一个指针,可以记住这样一个规律。先“pin”住一个节点,或者有新的指针指向它,那么指向这个节点就有两个指针了,9⃣️的指针就可以被改变。
Reverse Linked List这道题是reverse整个的linked list,翻转的是dummy和nullptr之间的链表串。那么对于reverse第m到n个元素之间的链表串,同样也可以这么做,只要找到相对应的dummy(链表之前的一个node)和对应的nullptr(要翻转的链表之后的那个node)就可以了。
但是如果我们one-pass,那么就需要一个count,计算我们移动了几个node。
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
ListNode* begin;
//ListNode* end;
ListNode* dummy = new ListNode(-1);
ListNode* cur=dummy;
int count=0;
if(head==nullptr)
return nullptr;
dummy->next = head;//begin before start(dumy), end after start(nullptr)
for(int i=1;i<m;++i){
cur=cur->next;
}
begin=cur;
cur=dummy;
/*for(int i=0;i<=n;++i){
cur=cur->next;
}
end=cur;*/
ListNode* flag=begin->next;
while(flag->next!=nullptr&&count<n-m){<span style="white-space:pre"> </span>//<span style="font-family: Arial, Helvetica, sans-serif;">flag->next!=end</span>
ListNode* new_next=flag->next->next;
flag->next->next=begin->next;
begin->next=flag->next;
flag->next=new_next;
count++;
}
return dummy->next;
}
};
第三道题Reverse Linked List in K-group也是同理,跟上面题一样,找到要翻转的链表之前对应的dummy节点和之后对应的nullptr节点。
class Solution {
public:
ListNode* reverseKGroup(ListNode *head, int k) {
ListNode* dummy = new ListNode(-1);
dummy->next = head;
ListNode* cur = dummy->next;
ListNode* pre = dummy;
ListNode* next = nullptr;
int count=0;
while(cur!=nullptr){
count++;
next = cur->next;
if(count==k){
count=0;
pre = reverse(pre, next);
}
cur=next;
}
return dummy->next;
}
private:
ListNode* reverse(ListNode *pre, ListNode *end){
ListNode* head;
ListNode* cur;
head = pre->next;
//cur = head->next;
while(head->next!=end){
ListNode* next = head->next->next;
head->next->next = pre->next;
pre->next = head->next;
head->next=next;
}
head->next = end;
return head;
}
};