leetcode-725-分隔链表
[博客链接]
[题目链接]
[github地址]
[题目描述]
给你一个头结点为 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
思路一:双指针
- 第一次遍历出链表长度
- 然后根据目标份数k取余i,除得结果b
- 前i个长度为b+1,后面的都为b
public ListNode[] splitListToParts(ListNode root, int k) {
//定义长度为k的数组
ListNode[] res = new ListNode[k];
//corner case
if (root == null) {
Arrays.fill(res, null);
return res;
}
//获得链表长度
int len = 0;
ListNode dummy = root;
while (dummy != null) {
len += 1;
dummy = dummy.next;
}
ListNode ins = root;
//k >= len 数组每个元素只能存一个listnode 或者null
if (k >= len) {
for (int i = 0; i < len; i++) {
if (ins != null) {
res[i] = new ListNode(ins.val);
ins = ins.next;
}
}
for (int i = len; i < k; i++) {
res[i] = null;
}
return res;
}
//可以存多个 前mod个元素 要有std+ 1个listnode 之后的k- mod个元素 只有std个元素
int mod = len % k;
int std = len / k;
ListNode slow = root;
ListNode fast = slow;
for (int i = 0; i < k; i++) {
if (i < mod){
//快指针移动std+1 个位置
for (int j = 1; j < std+1; j++) {
fast = fast.next;
}
ListNode temp = fast.next;
fast.next = null;
res[i] = slow;
slow = temp;
fast = slow;
}else {
//快指针移动std+1 个位置
for (int j = 1; j < std; j++) {
fast = fast.next;
}
ListNode temp = fast.next;
fast.next = null;
res[i] = slow;
slow = temp;
fast = slow;
}
}
return res;
}
- 时间复杂度:O()
- 空间复杂度:O()