问题:给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
/**
* 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) {}
* };
*/
算法:head 头结点没有前驱结点,设为 nullptr ,当 cur 不为空时,一直反转。
代码:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode *cur = head,*pre = nullptr;
while(cur){
ListNode *nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
}
return pre;
}
};
问题:给你单链表的头指针 head
和两个整数 left
和 right
,其中 left <= right
。请你反转从位置 left
到位置 right
的链表节点,返回 反转后的链表 。
/**
* 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) {}
* };
*/
算法:设置哨兵结点 dummy 指向头结点 head ,先找到 left 位置的前驱结点,然后反转从 left 位置到 right 位置的所有结点,最后连接两端。
代码:
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
ListNode dummy(0,head);// 哨兵结点
ListNode* p0 = &dummy;
for(int i = 0;i < left - 1;i++) p0 = p0->next;// p0 指向 left-1 位置
ListNode *pre = nullptr, *cur = p0->next;// pre(前驱结点)设空,cur(当前结点)指向 left 位置的结点
for(int i = left - 1;i < right;i++){
ListNode* nxt = cur->next;//nxt(后驱结点)
// 反转
cur->next = pre;
pre = cur;
cur = nxt;
}
//此时 pre 为 right 位置的结点,cur 为 right 后面位置的结点
p0->next->next = cur;// p0->next 是 left 位置的结点 ,连接此结点和 cur (即 right 后面的结点)
p0->next = pre;// 连接 p0 和 pre(反转只连接了从 left 到 right 之间的结点)
return dummy.next;// 返回哨兵结点的 next (即头结点)
}
};
问题:给你链表的头节点 head
,每 k
个节点一组进行翻转,请你返回修改后的链表。
k
是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k
的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
/**
* 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) {}
* };
*/
算法:先统计结点个数,然后每组单独处理,类似上一题,连接完结点后将 p0 指向下一组开始的地方。
代码:
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
// 统计结点个数
int n = 0;
for (ListNode* cur = head; cur; cur = cur->next) n++;
// 哨兵结点
ListNode dummy(0,head);
ListNode* p0 = &dummy;
ListNode* pre = nullptr;
ListNode* cur = head;
// k 个一组处理
for(;n >= k;n -= k){
for(int i = 0;i < k;i++){
ListNode* nxt = cur->next;
cur->next = pre;
pre = cur;
cur = nxt;
}
ListNode* nxt = p0->next;
p0->next->next = cur;
p0->next = pre;
p0 = nxt;// 下一组的开始
}
return dummy.next;
}
};