一、題目
給出一個鏈表,每 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