leetcode.725 题目地址
题目
给你一个头结点为 head 的单链表和一个整数 k ,请你设计一个算法将链表分隔为 k 个连续的部分。
每部分的长度应该尽可能的相等:任意两部分的长度差距不能超过 1 。这可能会导致有些部分为 null 。
这 k 个部分应该按照在链表中出现的顺序排列,并且排在前面的部分的长度应该大于或等于排在后面的长度。
返回一个由上述 k 部分组成的数组。
// exp1
head: 1->2-> 3, k = 5 => ListNode[]: [[1], [2], [3], [], []]
// exp2
head: 1->2->3->4->5->6->7->8->9->10, k=3 => ListNode: [[1,2,3,4],[5,6,7],[8,9,10]]
自己第一遍折腾扣出来的
function splitListToParts2(head, k){
// 现获取链表长度 len
let len = 0
let cur = head
while (cur) {
cur = cur.next
len++
}
// 分成k组, 根据题意,我们需要获取每一组的数量最少应该是 num 个
const num = Math.floor(len / k)
// 取余rem,记录下会有几个是num + 1个
let rem = len % k
// 创建一个结果数组
const ret = []
cur = head
// 当 k > len 的时候 直接每一项一个单独的节点,然后len -> k push空节点
if (k > len) {
for (let i = 0; i < k; i++) {
if (cur) {
ret.push(new ListNode(cur.val))
cur = cur.next
} else {
ret.push(null)
}
}
return ret
}
// 这里是过去ret的每一项的值
function getSingle(n) {
// 用tmp存在当前指针
let tmp = cur
// 新建指针来处理截断,
let p = cur
// cur 指针 逐步 指向下一个,来获取新的每一项的头节点
cur = cur.next
for (let j = 1; j < n; j++) {
if (!cur) break
p = p.next
cur = cur.next
}
// 这里截断 是我们的tmp是n个节点
p.next = null
return tmp
}
// 当前指针指向头节点
cur = head
// 我们需要每一项有num个节点,当有余数的时候,我们ret前面rem项的每一项都是n + 1个节点
// 所以我们先处理这个余数rem的问题
for (let i = 0; i < rem; i++) {
// 这里过去到第i项的节点是tmp
const tmp = getSingle(num + 1)
// push下
ret.push(tmp)
}
// 来处理基本数量num个的部分, 这里我们还剩下k - rem 项, 上一个步骤我们已经push了rem项
// 和上面的步骤一样,不同点是
// 1. 当前指针有可能是空,2. 不为空的时候, 我们每一下都是num个
for (let i = 0; i < k - rem; i++) {
if (cur) {
let tmp = getSingle(num)
ret.push(tmp)
} else {
ret.push(null)
}
}
// 最终得到结果
return ret
}
看下题解
。。。三个点表示对自己的无语, 代码量就比我少了很多。。
虽然思路是对的,但是处理方式和写法着实差太多了
看完题解我再来重新写一下
function splitListToParts(head, k) {
let len = 0
let cur = head
while(cur) {
cur = cur.next
len++
}
let num = Math.floor(len / k)
let rem = len % k
// 到这里都是一样的
// step1
const ret = Array.from({length: k}).fill(null)
// step2
for (let i = 0; i < k && cur; i++) {
// step3
ret[i] = cur
const n = i < rem ? num + 1 : num // step4
for (let j = 0; j < n; j++) {
cur = cur.next
}
const next = cur.next // step5
cur.next = null
cur = next
}
return ret
}
改进学习
- step1: 创建符合k项的数组
- step2: 结合第一步 处理 K大于长度是的情况
- step3:截取前n个节点的方法(我的方法太chun了)
- step4:处理每一项的链表长度
- step5:结合step3 去除前n个节点的处理
总结
编程能力。。。