leetcode每日一题指k个一组反转链表
题目链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group/submissions/
题目描述:
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
例子:
输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]
题解:
今天的这道题本以为反转链表会了一下就做出来了,结果写了好久发现还是不对,链表的题真是恶心到我了。
然后看了题解,才恍然大悟。
我是看题解看懂的,所以敲了两遍,但是不知道如何描述,全都在注释里面。代码如下:
代码如下:
public ListNode reverseKGroup(ListNode head, int k) {
//如果只有一个节点或者没有节点,直接返回
if (head == null || head.next == null) {
return head;
}
//定义一个假的节点。
ListNode dummy = new ListNode(0);
//假节点的next指向head。
// dummy->1->2->3->4->5
dummy.next = head;
//初始化pre和end都指向dummy。pre指每次要翻转的链表的头结点的上一个节点。end指每次要翻转的链表的尾节点
ListNode pre = dummy;
ListNode end = dummy;
//注意这里的条件是ens.next != null,也就是假如链表节点个数是k的整数倍的话,反转完后end指向最后一个节点,如果下一个没有了就结束循环,如果还有但是小于k个下面的循环和判断条件会控制
while (end.next != null) {
//循环k次,找到需要翻转的链表的结尾,这里每次循环要判断end是否等于空,因为如果为空,end.next会报空指针异常。
//dummy->1->2->3->4->5 若k为2,循环2次,end指向2
for (int i = 0; i < k && end != null; i++) {
end = end.next;
}
//如果end==null,即需要翻转的链表的节点数小于k,不执行翻转。
if (end == null) {
break;
}
//先记录下end.next,方便后面链接链表
ListNode next = end.next;
//然后断开链表
end.next = null;
//记录下要翻转链表的头节点
ListNode start = pre.next;
//翻转链表,pre.next指向翻转后的链表。1->2 变成2->1。 dummy->2->1
//这里的pre和dummy是一样的指向,因此pre.next相当于变成了dummy->2->1
pre.next = reverse(start);
//翻转后头节点变到最后。通过.next把断开的链表重新链接。
start.next = next;
//将pre换成下次要翻转的链表的头结点的上一个节点。即start
pre = start;
//翻转结束,将end置为下次要翻转的链表的头结点的上一个节点。即start
end = start;
}
return dummy.next;
}
//链表翻转
// 例子: head: 1->2->3->4
public ListNode reverse(ListNode head) {
//单链表为空或只有一个节点,直接返回原单链表
if (head == null || head.next == null) {
return head;
}
//前一个节点指针
ListNode preNode = null;
//当前节点指针
ListNode curNode = head;
//下一个节点指针
ListNode nextNode = null;
while (curNode != null) {
nextNode = curNode.next;//nextNode 指向下一个节点,保存当前节点后面的链表。
curNode.next = preNode;//将当前节点next域指向前一个节点 null<-1<-2<-3<-4
preNode = curNode;//preNode 指针向后移动。preNode指向当前节点。
curNode = nextNode;//curNode指针向后移动。下一个节点变成当前节点
}
return preNode;
}
```