题目
725. 分隔链表
给你一个头结点为 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 。前面部分的长度大于等于后面部分的长度。
思路:
这题的思路其实没什么弯弯绕绕,正常分析就ok。
- 遍历链表,求出链表长度length
- 算出每个链表的基础长度 eachLength = Math.floor(length/k)
- 如果length/k除不尽,那么多出来的应该要分配给前面的部分,算出多出来的部分excess = length%k
- 遍历链表k次,则可将链表分成k份
- 遍历过程中,求出当前这一份的长度,这里就看当前是不是前excess份,是的话就 +1
- 然后再将cur节点向前推荐curLength-1次,这时候就是这一部分的末尾节点
- 如果末尾节点不是null,则做链表切断操作
- 最终返回数组result即可
代码:
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode[]}
*/
var splitListToParts = function(head, k) {
let cur = head;
let length = 0;
while(cur){
cur = cur.next;
length++;
}
let eachLength = Math.floor(length/k);
let excess = length%k;
cur = head;
let result = [];
for(let i=0;i<k;i++){
result[i] = cur;
let curLength = eachLength + (i<excess?1:0);
for(let j=1;j<curLength;j++){
cur = cur.next;
}
if(cur){
let tmp = cur.next;
cur.next = null;
cur = tmp;
}
}
return result;
};