这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战 | 创作学习持续成长,夺宝闯关赢大奖 - 掘金 (juejin.cn)
题目链接
题解及分析
分隔链表
给你一个头结点为head的单链表和一个整数k,请你设计一个算法将链表分隔为k个连续的部分。
每部分的长度应该尽可能的相等:任意两部分的长度差距不能超过1。这可能会导致有些部分为null 。
这k个部分应该按照在链表中出现的顺序排列,并且排在前面的部分的长度应该大于或等于排在后面的长度。
返回一个由上述k部分组成的数组。
示例 1:![]()
输入:head = [1,2,3], k = 5
输出:[[1],[2],[3],[],[]]
解释:
第一个元素 output[0] 为 output[0].val = 1 ,output[0].next = null 。
最后一个元素 output[4] 为 null ,但它作为 ListNode 的字符串表示是 [] 。
思路:
- 用一个计数器来保存链表的长度
- 计算每一个部分的长度size,注意取余
- 循环k,为每一个部分填入内容
- 循环size,计算截断的位置
- 每个部分结束的位置的next为下个部分的开始
var splitListToParts = function(head, k) {
let count = 0
let counter = head
while(counter) {
counter = counter.next
count++
}
// 注意余数
let quotient = Math.floor(count / k)
let remainder = count % k
const parts = new Array(k).fill(null)
let cur = head
for(let i = 0; i < k && cur != null; i++) {
parts[i] = cur
// 当i<remainder的时候,即代表需要分配余数给当前数组
let size = quotient + (i < remainder ? 1 : 0)
for (let j = 1; j < size; j++) {
cur = cur.next;
}
const next = cur.next
cur.next = null
cur = next
}
return parts
}
分割链表
给你一个链表的头节点head和一个特定值x,请你对链表进行分隔,使得所有小于x的节点都出现在大于或等于x的节点之前。
你不需要保留每个分区中各节点的初始相对位置。示例 1:
![]()
输入: head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]
思路: 这道题并没有什么难度...
- 用两个新链表分别保存大于x和小于x的节点
- 重新组装链表
var partition = function(head, x) {
let small = new ListNode(0)
const smallHead = small
let large = new ListNode(0)
const largeHead = large
while(head !== null) {
if (head.val < x) {
small.next = head
small = small.next
} else {
large.next = head
large = large.next
}
head = head.next
}
large.next = null
small.next = largeHead.next
return smallHead.next
}
题目总结
这些道题目的特点是寻找特殊的链表中的某个节点,我们需要注意的是如何找到需要操作的节点以及如何对该操作进行优化