24. 两两交换链表中的节点 - 力扣(LeetCode)
定义三个指针,交换前先保存ntnt指针为next->next,cur和next两个节点,然后将pre->next指向next
若pre为空,说明当前交换的节点为头两个节点,不需要修改pre->next
若cur不为空而next为空,则将pre->next指向cur
然后根据ntnt更新三个节点,当cur或者next为nullptr时,终止交换
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode *pre = nullptr;
ListNode *cur = head, *next = nullptr;
if (cur) next = cur->next;
if (next) head = next;
while (next && cur)
{
ListNode *ntnt = next->next;
next->next = cur; cur->next = nullptr;
if (pre) pre->next = next;
pre = cur, cur = ntnt;
if (cur) next = cur->next;
}
if (pre && cur && (next == nullptr)) pre->next = cur;
return head;
}
};
25. K 个一组翻转链表 - 力扣(LeetCode)
先统计俩表中节点的数量n,需要翻转(n / k)组链表
使用哨兵new_head作为伪头节点
记录上一次k组的尾节点,初始为new_head
翻转完一组节点,将尾节点的next指向刚才翻转一组节点的头节点
对于每组节点的翻转,使用三个指针,将pre->cur修改cur->pre,再用next更新两个指针(pre = cur,cur = next)
每个子链表需要翻转k - 1次,一共需要翻转n / k组
最后,若k不能整除n,那么将上一组节点的尾节点next指向剩下节点的头节点
若k能整除n,那么将上一组节点的尾节点next指向nullptr
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
int n = 0;
ListNode *cur = head;
while (cur)
{
cur = cur->next;
n ++ ;
}
ListNode *new_head = new ListNode;
ListNode *pre = head;
ListNode *hhead = nullptr, *tail = new_head;
if (pre) cur = pre->next;
for (int i = 0; i < n / k; ++ i)
{
ListNode *new_tail = pre;
for (int j = 0; j < k - 1; ++ j)
{
ListNode *next = cur->next;
cur->next = pre;
pre = cur, cur = next;
}
hhead = pre, tail->next = hhead, tail = new_tail;
if (cur) pre = cur, cur = cur->next;
}
if (n % k) tail->next = pre;
else tail->next = nullptr;
return new_head->next;
}
};