题目
给你一个头结点为 head 的单链表和一个整数 k ,请你设计一个算法将链表分隔为 k 个连续的部分。每部分的长度应该尽可能的相等:任意两部分的长度差距不能超过 1 。这可能会导致有些部分为 null 。这 k 个部分应该按照在链表中出现的顺序排列,并且排在前面的部分的长度应该大于或等于排在后面的长度。返回一个由上述 k 部分组成的数组。
示例 1:
输入:head = [1,2,3], k = 5
输出:[[1],[2],[3],[],[]]
解释:
第一个元素 output[0] 为 output[0].val = 1 ,output[0].next = null 。
最后一个元素 output[4] 为 null ,但它作为 ListNode 的字符串表示是 [] 。
示例 2:
输入:head = [1,2,3,4,5,6,7,8,9,10], k = 3
输出:[[1,2,3,4],[5,6,7],[8,9,10]]
解释:
输入被分成了几个连续的部分,并且每部分的长度相差不超过 1 。前面部分的长度大于等于后面部分的长度。
提示:
- 链表中节点的数目在范围
[0, 1000]
0 <= Node.val <= 1000
1 <= k <= 50
解题思路
1.我们先对链表进行遍历,并获取链表长度len
2.我们用 len 对 k 进行取余 得到每组的元素个数temp,因为我们不能确定head 可以整除k ,所以我们再用 len 除以 k 得到余数,再将余数分配到我们已经分好的组中(举个例子: 11 / 3 = 3 余 2: 一共有3段,每段平均3个节点,但是剩下了2个节点,剩下的2个节点不能丢,得全部塞到子链表里面去,怎么塞呢?根据题意长的链表排前面,短的链表排后面,所以只有前面的两个子链表一人分担一个多余的节点,如此一来便形成了 4 4 3 的结构。)
3.分好组后我们设置一个哨兵结点 pre 再次对链表进行遍历,将链表截取为我们所划分好的长度。
代码实现
class Solution {
public ListNode[] splitListToParts(ListNode head, int k) {
ListNode cur = head;
int len = 0;
while(cur != null){
len++;
cur = cur.next;
}
int num = len / k;
int temp = len % k;
ListNode[] result = new ListNode[k];
ListNode pre = head;
for(int i = 0; i < k && pre != null; i++){
result[i] = pre;
int templen = num + (i < temp ? 1 : 0);
for(int j = 1; j < templen; j++){
pre = pre.next;
}
ListNode preNext = pre.next;
pre.next = null;
pre = preNext;
}
return result;
}
}
测试结果