前言
链表操作的核心问题之一,就是断链,不断链就需要把后面的被动节点先用指针变量指着。
一、分割链表
二、先取next再斩断链表
package everyday.listNode;
// 分割链表
public class SplitListToParts {
/*
target:给定链表和分成多少份,分割链表。
只要能确定每个链表分割多少个节点,遍历链表,就可以完成分割。
如何确定每个链表分割多少节点?链表长度len 对份数取余 & 对份数取商。
取余,为了得到前几个可以多分一个节点;取商,为了确定一个链表分到的基本节点个数。
*/
public ListNode[] splitListToParts(ListNode head, int k) {
// 返回k个链表。
ListNode[] ans = new ListNode[k];
// 遍历链表,求得链表长度。
int len = 0;
ListNode p = head;
while (p != null && (p = p.next) == p) ++len;
// 取余,为了得到前几个可以多分一个节点。
int mod = len % k;
// 取商,为了确定一个链表分到的基本节点个数。
int val = len / k;
// 开始分割,并赋值。
int idx = 0;
p = head;
while (idx < k) {
// 如果已经没有可分割的情况,则后面的每一个只能分到null.
if (p == null) {
ans[idx++] = null;
continue;
}
// 能分到非null节点,把初始节点赋值到数组中。
ans[idx++] = p;
// 根据当前能分到的节点数来分割链表。
for (int i = 1;i < (mod != 0 ? 1 : 0) + val;i++) p = p.next;
// 拿到下一个节点,并斩断链表。
ListNode next = p.next;
p.next = null;
// 设置好新链表的初始节点,开始下一轮的赋值。
p = next;
// mod表示前面有多少链表可以分到额外的一个节点,直至分完。
if (mod > 0) --mod;
}
// 返回填充好的链表数组。
return ans;
}
// 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;
}
}
}
总结
1)不想断链就需要把后面的被动节点先用指针变量指着。
参考文献
[1] LeetCode 分割链表