描述
将给出的链表中的节点每 k 个一组翻转,返回翻转后的链表
如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。
示例1
输入:
{1,2,3,4,5},2
返回值:
{2,1,4,3,5}
示例2
输入:
{},1
返回值:
{}
思路
将链表按照k个一组拆分,拆分成一个List,然后对每一个拆分后的链表进行反转,最后把这些反转后的拼接起来,形成一个新的链表。
注意,最后一个链表长度如果不是k的倍数,不用反转。
/**
* k个一组拆分链表
**/
private List<ListNode> splitNode(ListNode head, int k) {
List<ListNode> list = new ArrayList<>();
ListNode cur = head;
ListNode pHead = head;
int i = 0;
while (cur != null) {
if ((++i) % k == 0) {
list.add(pHead);
pHead = cur.next;
cur.next = null;
cur = pHead;
} else {
cur = cur.next;
}
}
if (pHead != null) {
list.add(pHead);
}
return list;
}
全部代码如下所示:
public ListNode reverseKGroup (ListNode head, int k) {
if (head == null || head.next == null) {
return head;
}
List<ListNode> list = splitNode(head, k);
ListNode nHead = new ListNode(-1);
ListNode lastTail = null;
for (int i = 0; i < list.size(); ++i) {
ListNode newHead = list.get(i);
/**
* 最后一个长度小于k的不反转,其余都反转
*/
if (i < list.size() - 1 || getLength(newHead) == k) {
newHead = reverse(list.get(i));
}
if (lastTail != null) {
lastTail.next = newHead;
} else {
nHead.next = newHead;
}
lastTail = getTail(newHead);
}
return nHead.next;
}
/**
* 反转链表
*/
private ListNode reverse(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode cur = head.next;
head.next = null;
ListNode pnext = null;
while (cur != null) {
pnext = cur.next;
cur.next = head;
head = cur;
cur = pnext;
}
return head;
}
private ListNode getTail(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode tail = head;
while (tail.next != null) {
tail = tail.next;
}
return tail;
}
private int getLength(ListNode head) {
ListNode p = head;
int ret = 0;
while (p != null) {
p = p.next;
ret++;
}
return ret;
}