分隔链表
题目描述
给你一个头结点为 head 的单链表和一个整数 k ,请你设计一个算法将链表分隔为 k 个连续的部分。
每部分的长度应该尽可能的相等:任意两部分的长度差距不能超过 1 。这可能会导致有些部分为 null 。
这 k 个部分应该按照在链表中出现的顺序排列,并且排在前面的部分的长度应该大于或等于排在后面的长度。
返回一个由上述 k 部分组成的数组。
输入:head = [1,2,3], k = 5
输出:[[1],[2],[3],[],[]]
解释:
第一个元素 output[0] 为 output[0].val = 1 ,output[0].next = null 。
最后一个元素 output[4] 为 null ,但它作为 ListNode 的字符串表示是 [] 。
解题思路
先对链表进行一次扫描,得到总长度len,再将链表划分为 k份,得到每组需要划分的个数,在计算出不够均分给每组的个数也就是余数,不过此时要考虑:当总结点数不够划分k组的情况,此时需要至少分配一个,然后余数为负值不影响后续对n的判断。然后在循环k轮,每划分一组在其后面插入null作为划分。
代码
class Solution {
public ListNode[] splitListToParts(ListNode head, int k) {
ListNode []ans=new ListNode[k];
ListNode p=head;
int len=0;
//求链表总长
while(p!=null){
p=p.next;
len++;
}
int term=len/k;
if(term==0)term++;
//要考虑之后对n的判断条件,若利用%求余数,下方if对n的判断应一致
//如:n=len%k
//if(!n=0)或if(n>0)则会对len<k情况判断错误
int n=len-term*k;
p=head;
//划分为k组
for(int i=0;i<k&&p!=null;i++){
ans[i]=p;
//每组的个数,并使其停在这组最后的位置,方便后续插入Null
for(int j=0;j<term-1;j++){
p=p.next;
}
//对余数进行均匀分配
if(n>0){
n--;
p=p.next;
}
//插入null
if(p!=null){
ListNode temp=p.next;
p.next=null;
p=temp;
}
}
return ans;
}
}