题目描述
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例:
给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
说明:
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
分析
反转链表的变形,思路比较简单,但是真写起来有很多细节的地方需要注意。
我自己的思路就是K个一组进行翻转,翻转后链接起来,不足的就不翻转
我的题解
public ListNode reverseKGroup(ListNode head, int k) {
if (k<=1)return head;
ListNode res = null;
//已经翻转了的头H,已经翻转了的尾T,下一个待翻转的头N
ListNode H = head;
ListNode T = head;
ListNode N = head.next;
ListNode tmp ;
int num ;//用于判断后面有没有K个节点
ListNode lastTail = null;
while (N!=null){
tmp = H;
num = 0;
while (tmp!=null && num<=k){
num++;
tmp = tmp.next;
}
if (num<k){//后面不足k个节点,结束
if (lastTail!=null)lastTail.next = H;
break;
}else{
//这4步用于交换两个节点
num = 0;//统计已经交换的节点
while (num<k-1){
T.next = N.next;
N.next = H;
H = N;
N = T.next;
num++;
}
if (lastTail==null)lastTail = T;
else{
lastTail.next = H;
lastTail = T;
}
if (res==null)res = H;//判断是不是第一次翻转k个,是就赋值res为第一次翻转的链表尾,即元链表的第k个
//切换到下一组
H = N;
T = N;
N = N==null?null: N.next;
}
}
if (res==null)res = head;
return res;
}
写得有点复杂了,感觉不太好。
看了下题解,有其他的解法:
- 可以使用递归,降低了逻辑上的复杂度
- 尾插法:就是组内把前面的搬到后面,翻转的不同方法而已,不过这里很适合。
- 辅助栈(题目要求常数空间,栈需要O(K)空间)
尾插法
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode pre = dummy;
ListNode tail = dummy;
while (true) {
int count = 0;
while (tail != null && count != k) {
count++;
tail = tail.next;
}
if (tail == null) break;
ListNode head1 = pre.next;
while (pre.next != tail) {
ListNode cur = pre.next;
pre.next = cur.next;
cur.next = tail.next;
tail.next = cur;
}
pre = head1;
tail = head1;
}
return dummy.next;
}
递归
public ListNode reverseKGroup(ListNode head, int k) {
ListNode cur = head;
int count = 0;
while (cur != null && count != k) {
cur = cur.next;
count++;
}
if (count == k) {
cur = reverseKGroup(cur, k);
while (count != 0) {
count--;
ListNode tmp = head.next;
head.next = cur;
cur = head;
head = tmp;
}
head = cur;
}
return head;
}
栈
public ListNode reverseKGroup(ListNode head, int k) {
Deque<ListNode> stack = new ArrayDeque<ListNode>();
ListNode dummy = new ListNode(0);
ListNode p = dummy;
while (true) {
int count = 0;
ListNode tmp = head;
while (tmp != null && count < k) {
stack.add(tmp);
tmp = tmp.next;
count++;
}
if (count != k) {
p.next = head;
break;
}
while (!stack.isEmpty()){
p.next = stack.pollLast();
p = p.next;
}
p.next = tmp;
head = tmp;
}
return dummy.next;
}