725. Split Linked List in Parts
题目链接
tag:
- Medium
- Linked
question:
Given the head of a singly linked list and an integer k, split the linked list into k consecutive linked list parts.
The length of each part should be as equal as possible: no two parts should have a size differing by more than one. This may lead to some parts being null.
The parts should be in the order of occurrence in the input list, and parts occurring earlier should always have a size greater than or equal to parts occurring later.
Return an array of the k parts.
Example1:
![](https://img.haomeiwen.com/i13533972/2ea581c7049182e8.png)
Input: head = [1,2,3], k = 5
Output: [[1],[2],[3],[],[]]
Explanation:
The first element output[0] has output[0].val = 1, output[0].next = null.
The last element output[4] is null, but its string representation as a ListNode is [].
Example2:
![](https://img.haomeiwen.com/i13533972/aa380e80b0c13a81.png)
Input: head = [1,2,3,4,5,6,7,8,9,10], k = 3
Output: [[1,2,3,4],[5,6,7],[8,9,10]]
Explanation:
The input has been split into consecutive parts with size difference at most 1, and earlier parts are a larger size than the later parts.
Constraints:
- The number of nodes in the list is in the range [0, 1000].
- 0 <= Node.val <= 1000
- 1 <= k <= 50
思路:这道题给我们一个链表和一个正数k,让我们分割链表成k部分,尽可能的平均分割,如果结点不够了,就用空结点,比如例一中的。如果无法平均分,那么多余的结点就按顺序放在子链表中,如例二中所示。我们要知道每个部分结点的个数,才能将整个链表断开成子链表,所以我们首先要统计链表中结点的总个数,然后除以k,得到的商avg就是能分成的部分个数,余数ext就是包含有多余的结点的子链表的个数。我们开始for循环,循环的结束条件是i小于k且root存在,要生成k个子链表,在循环中,先把头结点加入结果res中对应的位置,然后就要遍历该子链表的结点个数了,首先每个子链表都一定包含有avg个结点,这是之前除法得到的商,然后还要有没有多余结点,如果i小于ext,就说明当前子链表还得有一个多余结点,然后我们将指针向后移动一个,注意我们这里的j是从1开始,我们希望移动到子链表的最后一个结点上,而不是移动到下一个子链表的首结点,因为我们要断开链表。我们新建一个临时结点t指向下一个结点,也就是下一个子链表的首结点,然后将链表断开,再将root指向临时结点t,这样就完成了断开链表的操作,参见代码如下:
// O(n)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
vector<ListNode*> splitListToParts(ListNode* head, int k) {
ListNode* tmp = head;
int n = 0;
while (tmp) {
++n;
tmp = tmp->next;
}
vector<ListNode*> res(k ,nullptr);
int quotient = n / k, remainder = n % k;
ListNode* curr = head;
for (int i = 0; i < k && curr != nullptr; ++i) {
res[i] = curr;
int partsize = quotient + (i < remainder ? 1 : 0);
for (int j = 1; j < partsize; ++j) {
curr = curr->next;
}
ListNode* next = curr->next;
curr->next = nullptr;
curr = next;
}
return res;
}
};