LeetCode 25 - k个一组翻转链表
程序员文章站
2022-03-18 09:41:06
...
题目描述
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明 :
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
解法一:递归(C++)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if(head==nullptr||head->next==nullptr) return head;
ListNode* tail = head;
for(int i=0;i<k;i++)
{
if(tail==nullptr) return head;
tail = tail->next;
}
ListNode* newhead = reverse_subchain(head, tail);
head->next = reverseKGroup(tail, k);
return newhead;
}
ListNode* reverse_subchain(ListNode* head, ListNode* tail){
ListNode* pre = nullptr;
ListNode* next = nullptr;
while(head!=tail)
{
next = head->next;
head->next = pre;
pre = head;
head = next;
}
return pre;
}
};
关于 reverse_subchain函数解释如下:
解法二:用栈(Python)
如果题目没有要求只能使用常数的额外空间的话,此解法是个简单明了的解法
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
dummy = ListNode(0)
p = dummy
while True:
count = k
stack = []
tmp = head
while count and tmp:
stack.append(tmp)
tmp = tmp.next
count -= 1
# 注意,目前tmp在k+1的位置
# 说明剩下的结点不够一组
if count:
p.next = head
break
# 翻转
while stack:
p.next = stack.pop()
p = p.next
# 与剩下链表串起来
p.next = tmp
head = tmp
return dummy.next
解法三:尾插入(Python)
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
....
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
dummy = ListNode(0)
dummy.next = head
pre = dummy
tail = dummy
while True:
count = k
while count and tail:
count -= 1
tail = tail.next
if not tail: break
head = pre.next
while pre.next != tail:
cur = pre.next;
pre.next = cur.next
cur.next = tail.next
tail.next = cur
pre = head
tail = head
return dummy.next