携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情
今天确实是抽了,强硬挑战困难题
K个一组翻转链表
该题出自力扣的25题 —— K个一组翻转链表【困难题】,不过这算是困难题里面比较简单的
审题
给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
- k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
- 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
- 这道题确实是困难题里面比较简单的,并不会考究算法的深度,只是考验设计的全面性
- 给出一个链表的头结点,给出k的整数值,需要把链表按照K个为一组去反转,可以参考从前做过的一道题 —— 链表反转;利用那道题作为一个API去调用即可
- 拥有了一个调用的API,那么只需要对链表按照边界分组,需要判断K个是否会超出界限
- 反转后需要对链表进行拼接,需要保存反转的上一个节点,保存尾部节点;反转后调用next方法拼接
编码
/**
* 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) {
//进阶:你可以设计一个只用 O(1) 额外内存空间的算法解决此问题吗?
ListNode hair = new ListNode(0);
hair.next = head;
ListNode first = hair;
while (head != null){
// 2 先行判断是否到达k
ListNode tail = first;
for (int i = 0; i < k; i++) {
tail = tail.next;
if (tail == null){
return hair.next;
}
}
ListNode next = tail.next;
ListNode[] listNodes = reverseList(head, tail);
ListNode top = listNodes[0];
ListNode last = listNodes[1];
last.next = next;
first.next = top;
first = last;
head = last.next;
}
return hair.next;
}
public ListNode[] reverseList(ListNode head,ListNode tail) {
ListNode prev = tail.next;
ListNode cur = head;
while (prev != tail){
ListNode next = cur.next;
cur.next = prev;
prev = cur;
cur = next;
}
return new ListNode[]{tail,head};
}
}