一、题目
给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
二、解题
创建四个指针,分别为p=head和q=head?.next,p的k个节点的尾部pTail=nil,q的头部qHead=head。
使用while遍历链表,同时使用i计数,移动指针q,将q移动到p的头部。当i==k时,如果pTail不为空,将将p添加到pTail后面,同时记录当前的p的尾部pTail和q的头部qHead。并将p和q向后移动到下一组节点。之后需要处理一个额外情况,当剩下的节点不足k个时,需要将之后的节点在翻转会原样。
时间复杂度为O(n)。
步骤
三、代码实现
class Solution {
func reverseKGroup(_ head: ListNode?, _ k: Int) -> ListNode? {
if head == nil || k == 0{
return head;
}
var result: ListNode? = nil;
var preTail: ListNode? = nil;
var currentTail: ListNode? = head;
var p,q,r: ListNode?
p = head
q = head?.next;
p?.next = nil
var i = 1
while q != nil {
r = q?.next;
q?.next = p;
p = q
q = r
i += 1
if i == k {
if result == nil {
result = p
}
if preTail != nil {
preTail?.next = p;
}
preTail = currentTail;
currentTail = q
if q != nil {
p = q;
q = q?.next;
}
currentTail?.next = nil;
i = 1
}
}
if currentTail != nil {
q = p?.next
p?.next = nil
while q != nil {
r = q?.next
q?.next = p;
p = q;
q = r;
}
preTail?.next = currentTail
}
if result == nil {
result = p
}
return result
}
}
Demo地址:github
网友评论