題目
- 給定一個單連結串列並給定其頭結點root,寫一個函式實現將其分割為k個連續的連結串列
- 每一部分連結串列的長度要求:兩個連結串列部分的長度不能超過1,某些連結串列可以置位空(null)
- 這些部分連結串列必須要按照輸入連結串列的順序,並且前一部分的長度必須大於等於後面部分的連結串列長度
- 返回一個分段連結串列頭節點組成的陣列
- 舉例來說給定輸入1->2->3->4, k = 5 返回[[1],[2],[3],[4],null]
- 給定root = [1, 2, 3], k = 5,返回[[1],[2],[3],[],[]]
- 給定root = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], k = 3,返回Output: [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]
解題思路
- 首先,給定一個k,一個連結串列,假設連結串列長度為length,也即是我們要將連結串列分為k部分,且每兩部分的長度不能超過1,那麼按照正常的思想我們就是均分唄,那樣就都是一樣的
- 但是現在問題來了,我們均分之後即是length/k不能整除,也即是存在餘數,此時餘數remain=length % k, 既然不能超過1那麼我們能做的只有取陣列的前remain個數,分別將它的節點數再加1就可以完成我們的目標,有點類似於我們有10個硬幣放進三個罐子,任意兩個罐子之間的差值不能大於1,按照均分每個罐子3個硬幣,此時還剩了一個硬幣,再按照從頭開始排放入第一個罐子形成4,3,3。如果是11個硬幣就是形成4,4,3以此類推
- 在我們確定了平均值和average和remain之後就可以開始給陣列裝填資料了,陣列中每個數對應的連結串列長度都應該是average或者average+1,形成一個陣列的遍歷
- 在陣列遍歷內部每次根據所需分段連結串列長度然後對連結串列進行遍歷,將分段尾節點的next修改為null,head存入陣列即可完成內迴圈,然後整體就完成了。
原始碼實現
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode[] splitListToParts(ListNode root, int k) {
ListNode[] result = new ListNode[k];
int count = 0;
ListNode index = root;
while (index != null) {
count++;
index = index.next;
}
int average = count/k;//平均的
int remaining = count % k;//剩餘的
index = root;
ListNode head = root;//每一段的頭
for (int i = 0; i < k; i++) {
int total = i < remaining ? average + 1 : average;
for (int j = 0; j < total - 1; j++) {
if (index != null) index = index.next;
}
result[i] = head;
ListNode last = index;
if (last != null) {
index = index.next;
head = index;
last.next = null;
} else head = null;
}
return result;
}
}