leetcode日常刷题
题目:K个一组翻转链表
思路
题目要求k个一组进行反转,首先考虑到如果k为1,那就可以直接返回链表头,这种情况没必要翻转。
如果只有一个节点或者head为空结点,直接返回head即可(一个节点翻转k次都是本身)
if(!head || !head->next || k==1) return head;
其次对于链表题型,在表头head前增加一个哑节点能省去很多麻烦(省去头节点特殊处理)
ListNode *dummy= new ListNode(0,head);// 哑节点
具体实现思路为:
根据上图,需要实现一个函数reverse实现子链表翻转,在reverseKGroup中需要不断前移指针,具体代码为:
class Solution {
public:
// 双指针反转链表,返回头节点和尾节点
vector<ListNode *> reverse(ListNode* head,ListNode *tail){
tail->next =nullptr; // 断链
ListNode * dummy= nullptr;
ListNode * head_next;
ListNode * sign; // 标记尾节点
while(head!=nullptr){
head_next =head->next;
head->next = dummy;
if(!dummy) sign = head;
dummy = head;
head = head_next;
}
return {dummy,sign};
}
ListNode* reverseKGroup(ListNode* head, int k) {
if(!head || !head->next || k==1) return head; // 空链表或单节点可以直接return
ListNode *dummy= new ListNode(0,head);// 哑节点
ListNode *pre_tail = dummy; // 记录tail前一个节点的指针
ListNode *tail = head;
ListNode *head_next; //记录head下一个节点的指针
while(true){
// head前移k-1次(因为head起点已经占了一个位置)
for(int i=0;i<k-1;i++) {
if(!head) return dummy->next;
head=head->next;
if(!head) return dummy->next;
}
head_next = head->next;
vector<ListNode*> reverse_res;
reverse_res = reverse(tail,head);
// 接回原链表
pre_tail->next = reverse_res[0];
reverse_res[1]->next = head_next;
// 确定head,tail新起点
pre_tail = reverse_res[1];
head =tail = head_next;
}
return dummy->next;
}
};