Day77 | 灵神 | 反转链表 反转链表 反转链表II K个一组翻转链表
206.反转链表
206. 反转链表 - 力扣(LeetCode)
思路:
笔者之前做过所以做的很快,简单来说用p指向现在的结点,pre指向p的前一个节点,用指向p的下一个节点
然后就是让p->next指向前一个节点pre,这是反转
再让前一个结点变成p,p变成q,这是往后继续遍历
也可以看灵神的视频讲解,有图示很快理解
反转链表【基础算法精讲 06】_哔哩哔哩_bilibili
完整代码:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | class Solution {public:
 ListNode* reverseList(ListNode* head) {
 ListNode *p=head;
 ListNode *pre=nullptr;
 while(p!=nullptr)
 {
 ListNode* q=p->next;
 p->next=pre;
 pre=p;
 p=q;
 }
 return pre;
 }
 };
 
 | 
92.反转链表II
92. 反转链表 II - 力扣(LeetCode)
思路:
这道题和上一题的区别就是在反转完链表以后,需要把反转的部分[2,3,4]接到这一段的前一个结点1和后一个节点5,如下图所示

所以我们就保存一下反转这段的前一个节点1,图中的p0,笔者用lpre表示,而后一个节点不需要保存,因为遍历结束的时候就是cur所指的,cur就是笔者的p指针,pre就是pre
所以反转结束后,把pre接到lpre后面
链表反转部分的第一个结点2反转后变成最后一个结点,把cur和2连上就构成了新的链表,然后返回头结点head就行
可是有一个问题
如果反转的部分不是2,3,4而是1,2,3呢,即left==1的情况?
那lpre不就不存在了嘛?
所以就需要建立一个虚拟头结点,只要建立一个虚拟头结点,那么所有的反转的情况都不可能是第一个节点开始,而我们要做的就是按照上面的思路按部就班就好了
完整代码:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 
 | class Solution {public:
 ListNode* reverseBetween(ListNode* head, int left, int right) {
 
 ListNode res(0,head);
 
 ListNode* l=&res;
 
 ListNode* lpre=&res;
 
 for(int i=0;i<left;i++)
 {
 if(i<left-1)
 lpre=lpre->next;
 l=l->next;
 }
 
 ListNode *p=l;
 ListNode *pre=nullptr;
 for(int i=0;i<right-left+1;i++)
 {
 ListNode* q=p->next;
 p->next=pre;
 pre=p;
 p=q;
 }
 
 lpre->next=pre;
 l->next=p;
 
 return res.next;
 }
 };
 
 | 
25.K个一组翻转链表
25. K 个一组翻转链表 - 力扣(LeetCode)
思路:
这道题和上一道题基本上没什么区别,就是上一道题是只需要反转一次,而这一道题需要反转多次,而每一次反转都需要让left和right增加k,并且left和right的间隔永远是k
上一道题是反转一次,我们保存了lpre,即left的上一个节点
那这道题是多次反转,那说明我们每次反转前都需要保存或者说更新left的上一个节点,以保证我们的链表可以是连起来,这里如果想不通的话记得去看看图示或者自己动手画一画
图示请看灵神的视频
反转链表【基础算法精讲 06】_哔哩哔哩_bilibili
完整代码:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 
 | class Solution {public:
 ListNode* reverseKGroup(ListNode* head, int k) {
 
 ListNode res(0,head);
 ListNode* cnt=res.next;
 
 int length=0;
 while(cnt!=nullptr)
 {
 length++;
 cnt=cnt->next;
 }
 
 ListNode* p=head;
 ListNode* pre=nullptr;
 ListNode* lpre=&res;
 
 for (; length >= k; length -= k)
 {
 for(int i=0;i<k;i++)
 {
 
 ListNode* q=p->next;
 p->next=pre;
 pre=p;
 p=q;
 }
 
 ListNode* nxt=lpre->next;
 lpre->next->next=p;
 lpre->next=pre;
 lpre=nxt;
 }
 
 return res.next;
 }
 };
 
 |