每日一题,防止痴呆 = =
一、题目大意
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group
二、题目思路以及AC代码
这题虽然LeetCode标记的是困难,但并没有用的算法,考察的我感觉只是指针理解和实现的问题。
我的思路是这样的,既然要求不能使用额外的存储空间,那肯定就是在原来的基础上改了,我们可以实现一个flipK(start, k)的函数,用来翻转从start节点开始的k个节点,而翻转的过程就是利用双指针,基本的思想是利用p和q两个相邻指针,首先保存q->next,然后令q->next = p,然后再将双指针向下移动,这样的好处是同时解决了两组翻转链表链接的问题,因为当双指针到最后的时候,q->next就是下面一组链表的头,所以我们只需要在最后,让p->next指向保存的q->next即可(但是后面发现其实不是这样,这部分还需要进行处理)
下面给出AC代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
void flipK(ListNode* head, int k) {
if (k == 1) return ;
ListNode* p = head; if (!p) return ;
ListNode* q = p->next; if (!q) return ;
while (--k) {
ListNode* r = q->next;
q->next = p;
p = q;
q = r;
}
head->next = q;
}
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
int cnt = 1;
ListNode* start = head;
ListNode* before_start = NULL;
ListNode* p = head;
bool flag = false;
while (p) {
ListNode* next = p->next;
if (cnt % k == 0) {
flipK(start, k);
if (!flag) {
flag = true;
head = p;
}
if (before_start) before_start->next = p;
before_start = start;
start = next;
}
cnt++;
p = next;
}
return head;
}
};
如果有问题,欢迎大家指正!!!