解法都在代码里,不懂就留言或者私信
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
/**1个1组反转吗?神经病啊 */
if(k == 1) {
return head;
}
/**题目已经给出k<=n了,所以无需验证k是否大于长度*/
int count = 0;
ListNode cur = head;
/**当前区间的头 */
ListNode curHead = head;
/**反转之后链表的头 */
ListNode newHead = null;
/**上个区间反转之后的结尾 */
ListNode preLast = null;
/**下一个节点用于遍历 */
ListNode next = null;
while(cur != null) {
/**路过节点就统计,而不是走一步统计,这样比较方便 */
count ++;
/**拿到当前的下个节点,因为cur的next指针会发生变化,所以需要提前拿到 */
next = cur.next;
/**如果够了k个 */
if(count == k) {
/**断开和后面的连接,方便当前区间的反转 */
cur.next = null;
/**反转当前区间 */
ListNode curHeadReverse = reverse(curHead);
/**如果前一个区间的尾巴不为空(当前不是第一个区间) */
if(preLast != null) {
preLast.next = curHeadReverse;
}
/**如果新的头为空(当前是第一个区间),给新的头赋值 */
if(newHead == null) {
newHead = curHeadReverse;
}
/**preLast是给下个区间用的,它的next指向下个区间反转之后的头 */
preLast = curHead;
/**当前区间的尾巴指向下个区间目前的头(反转之前的) */
curHead.next = next;
/**下个区间的头*/
curHead = next;
/**当前k个结束,count归0 */
count = 0;
}
cur = next;
}
return newHead;
}
/**经典的反转链表的题 */
public ListNode reverse(ListNode head) {
ListNode cur = head;
ListNode pre = null;
ListNode next = null;
while(cur != null) {
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
}
运行结果
肯定是最优解了,但是其中的遍历可以删除一点,其实无所谓的