[LeetCode]725. 分隔链表(java实现)
1. 题目
2. 读题(需要重点注意的东西)
- 返回的是一个存放着头节点的数组;
- l = len/ k为每组的长度
- r = len % k为余数
- 链表前面部分的长度应该大于后面部分的长度
思路:
用l表示每段的平均长度,如5个节点分为3段,5/3=1,平均长度为1,此时每段的长度分布为 : [[1],[1],[1]],但是1+1+1 = 3,总节点为5,因此余数为2也要加到每段中;用r表示余数,即有几段要加1,5%3=2,即前两段均要加1个节点,所以每段长度的分布为: [[1+1],[1+1],[1]] = [[2],[2],[1]]。
知道了每段的链表长度后,要执行的就只是断开链表的操作,以及要注意,有题目中所演示的 1->2->3->4, k = 5 // 5 结果 [ [1], [2], [3], [4], null ],返回有空的情况。
简而言之:1. 求每段长度;2. 分段。
3. 解法
/**
* 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; }
* }
*/
// len % k = 余多少个节点,len / k = 每组的平均长度
// pre节点用于在head节点前,断开链表,将链表分为不同的组
class Solution {
public ListNode[] splitListToParts(ListNode head, int k) {
ListNode[] ans = new ListNode[k]; // 创造最终返回的数组,有k个元素
int len = 0;
// 求链表长度的一种写法
for(ListNode node = head;node != null;node = node.next) len++;
// l表示每段的平均长度,如5个节点分为3段,5/3=1,平均长度为1,此时每段的长度分布为 : [[1],[1],[1]],但是1+1+1 = 3,总节点为5,因此余数为2也要加到每段中
int l = len/ k;
// r表示余数,即有几段要加1,5%3=2,即前两段均要加1个节点,所以每段长度的分布为: [[1+1],[1+1],[1]] = [[2],[2],[1]]
int r = len % k;
// 求出每段的长度后,要做的就只是在该分段的地方断开链表,然后存在数组中
ListNode node = head;
ListNode pre = null;
for(int i = 0;i < k;i++, r--){
ans[i] = node;
// 每段的长度 part_len
int part_len = l + (r > 0 ? 1 : 0);
// 根据每段的长度断开链表
for(int j = 0;j < part_len; j++){
pre = node;
node = node.next;
}
if(pre != null) pre.next = null;
}
return ans;
}
}