题目介绍
力扣725题:leetcode-cn.com/problems/sp…
方法一:拆分链表
题目要求将给定的链表分隔成 k
个连续的部分。由于分隔成的每个部分的长度和原始链表的长度有关,因此需要首先遍历链表,得到链表的长度 n
。
得到链表的长度 n
之后,记 quotient = n / k, remainder = n % k
,则在分隔成的 k 个部分中,前 remainder
个部分的长度各为 quotient+1
,其余每个部分的长度各为 quotient
。
分隔链表时,从链表的头结点开始遍历,记当前结点为 curr
,对于每个部分,进行如下操作:
-
将
curr
作为当前部分的头结点; -
计算当前部分的长度
partSize
; -
将
curr
向后移动partSize
步,则curr
为当前部分的尾结点; -
当
curr
到达当前部分的尾结点时,需要拆分curr
和后面一个结点之间的连接关系,在拆分之前需要存储curr
的后一个结点next
; -
令
curr
的next
指针指向null
,完成curr
和next
的拆分; -
将
next
赋值给curr
。
完成上述操作之后,即得到分隔链表后的一个部分。重复上述操作,直到分隔出 k
个部分,或者链表遍历结束,即 curr
指向 null
。
代码如下:
/**
* 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; }
* }
*/
class Solution {
public ListNode[] splitListToParts(ListNode head, int k) {
int n = 0;
ListNode temp = head;
while (temp != null) {
n++;
temp = temp.next;
}
//得到分隔的个数
int quotient = n / k;
//分隔之后剩余的个数,会填充在前面的分隔链表中
int remainder = n % k;
ListNode[] parts = new ListNode[k];
ListNode curr = head;
for (int i = 0; i < k && curr != null; i++) {
parts[i] = curr;
//分隔个数,如果还剩余的话,需要加上剩余个数
int partSize = quotient + (i < remainder ? 1 : 0);
//移动指针到下一个分隔链表的头节点的上一个节点
for (int j = 1; j < partSize; j++) {
curr = curr.next;
}
ListNode next = curr.next;
//断开链表,将上一个分隔链表的尾节点的next置为空
curr.next = null;
curr = next;
}
return parts;
}
}
复杂度分析
-
时间复杂度:O(n),其中 n 是链表的长度。需要遍历链表两次,得到链表的长度和分隔链表。
-
空间复杂度:O(1)。只使用了常量的额外空间,注意返回值不计入空间复杂度。