目录
题目:
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
进阶:
你可以设计一个只使用常数额外空间的算法来解决此问题吗?
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
先找到需要反转的链表片段的尾节点tail,
然后从头开始遍历链表片段,依次插入到tail后面,过程如下,1和2依次插入到3后面:
pre
tail head
dummy 1 2 3 4 5
# 我们用tail 移到要翻转的部分最后一个元素
pre head tail
dummy 1 2 3 4 5
cur
# 我们尾插法的意思就是,依次把cur移到tail后面
pre tail head
dummy 2 3 1 4 5
cur
# 依次类推
pre tail head
dummy 3 2 1 4 5
cur
....
如将1插入到3后面,过程:
c++代码:
/**
* 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) {
ListNode* dummy = new ListNode(0);
dummy->next = head;
ListNode* pre = dummy;
ListNode* tail = dummy;
while (true)
{
// 找到尾节点
for (int i = 0; i < k; i++)
{
tail = tail->next;
if (tail == nullptr) return dummy->next; // 不足k个了,返回前面已经反转后的结果
}
// 遍历
head = pre->next; // 备份开始的节点,因为这个节点会是下一次链表片段开始的节点
while (pre->next != tail) // 当tail没有被挤到前面之前
{
ListNode* cur = pre->next; // 当前需要插入到尾节点tail后的节点
// 将cur插入tail后
pre->next = cur->next;
cur->next = tail->next;
tail->next = cur;
}
// 更新下一个链表片段的头节点pre和尾节点tail
pre = head;
tail = head;
}
}
};
python代码:
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def reverseKGroup(self, head, k):
dummy = ListNode(0)
dummy.next = head
pre = dummy
tail = dummy
while True:
for i in range(k):
tail = tail.next # tail 移到要翻转的部分最后一个元素
if not tail:
return dummy.next
head = pre.next # 这里用于下次循环,反转之后前面的位置,就反转到了下次循环开始的位置
while pre.next != tail: #
cur = pre.next # 获取下一个元素
# pre与cur.next连接起来,此时cur(孤单)掉了出来
pre.next = cur.next
cur.next = tail.next # 和剩余的链表连接起来
tail.next = cur # 插在tail后面 尾插法的意思就是,依次把cur移到tail后面
# 改变 pre tail 的值
pre = head
tail = head
if __name__ == '__main__':
s = Solution()
p1 = ListNode(1)
p2 = ListNode(2)
p3 = ListNode(3)
p4 = ListNode(4)
p5 = ListNode(5)
p1.next = p2
p2.next = p3
p3.next = p4
p4.next = p5
a = s.reverseKGroup(p1, 3)
print(a)