labuladong如何k个一组反转链表
利用栈先进后出,反转k个一组的链表
- stack中存放的是ListNode
- 虽然存放在stack中,但ListNode之间的指向关系仍然保留
以 1->2->3->4->5 为例,
- 先在最左边加一个dummy头(-1)便于操作。
- 注意:大循环
while cur
里面的while n>0 and cur 一定要有,确保不够k个Node时n>0,及时跳出(否则cur=cur.next也没有意义了)。 - 第一次while时,stack中存放 [3,2,1],pre产生的结果是: -1->3->2->1 。此时cur 指向4,pre指向3。
pre.next=cur
后现在的结果是-1->3->2->1->4->5 - 第二次while时,stack中存放[5,4],但是由于n!=0,直接break出循环(即
pre.next=cur
不执行)。此时cur已经指向5后面的None,但是现在已经跳出while循环了,不必理会cur。- else break这里用else continue也可以,反正此时cur==nullprt,也要跳出while循环
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseKGroup(self,head, k):
dummy=ListNode(-1)
dummy.next=head
pre=dummy
cur=head
stack=[]
while cur:
# while True:
n=k
while n>0 and cur:
stack.append(cur)
cur=cur.next
n-=1
if n==0:
while stack:
pre.next=stack.pop()
pre=pre.next
else:
break
pre.next=cur
return dummy.next
- 其他写法
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def reverseKGroup(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
# 在最左边加一个dummy头(-1)便于操作
dummy = ListNode(-1)
dummy.next=head
pre = dummy
cur = head
stack = []
count = 0
while cur:
# 把k个节点加到stack中
while cur and count < k:
stack.append(cur)
cur = cur.next
count += 1
# 当stack中存了k个节点时,pop出这些节点,并逐个加到pre后面
if count == k:
while stack:
pre.next = stack.pop()
pre = pre.next
count -= 1
else:
break # 如果不够k个,则跳出while cur循环
# 不用担心跳出以后后面的节点
# pre已经在这次的if语句执行前通过pre.next=cur 把后面的节点连在一起了
pre.next = cur
return dummy.next
- 注意C++中栈的操作,在top后要pop
- s.pop() 删除栈顶元素但不返回其值
- s.top() 返回栈顶的元素,但不删除该元素
- s.push() 在栈顶压入新元素
/**
* 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(-1);
dummy->next = head;
ListNode *pre=dummy;
ListNode *cur=head;
stack < ListNode * > stk;
while (cur!=nullptr){
// 不管够不够k个,都尽量入栈
for (int i = 0; i < k && (cur!=nullptr); ++i) {
stk.push(cur);
cur=cur->next;
}
// 如果栈中有k个元素,则把这一组进行出栈并拼接
if (stk.size()==k){
while(!stk.empty()){
pre->next=stk.top();
stk.pop();
pre=pre->next;
}
}else break; // 这里用continue也可以,反正此时cur==nullprt,也要跳出while循环
pre->next = cur; // 每组操作后,把cur接到pre后面
}
return dummy->next;
}
};
其他写法:
/** * 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(-1); dummy->next = head; ListNode *pre = dummy; ListNode *cur = head; stack<ListNode *> s; int count = 0; while (cur != nullptr) { while (cur != nullptr && count < k) { s.push(cur); cur = cur->next; count += 1; } if (count == k) { while (!s.empty()) { pre->next = s.top(); s.pop(); pre = pre->next; count -= 1; } } else break; pre->next = cur; } return dummy->next; } };
- 补充:如果题目变成:后面不够的也要反转,只要把
else break
改成: (也就是把后面的stack中的节点pop出,并拼接到pre后即可)
else:
while stack:
pre.next = stack.pop()
pre = pre.next
count -= 1