LeetCode 题解工作台

分隔链表

给你一个头结点为 head 的单链表和一个整数 k ,请你设计一个算法将链表分隔为 k 个连续的部分。 每部分的长度应该尽可能的相等:任意两部分的长度差距不能超过 1 。这可能会导致有些部分为 null 。 这 k 个部分应该按照在链表中出现的顺序排列,并且排在前面的部分的长度应该大于或等于排在后面…

category

1

题型

code_blocks

5

代码语言

hub

3

相关题

当前训练重点

中等 · 链表指针操作

bolt

答案摘要

我们先遍历链表,得到链表的长度 ,然后我们计算出平均长度 $\textit{cnt} = \lfloor \frac{n}{k} \rfloor$ 和余数 $\textit{mod} = n \bmod k$。那么对于前 个部分,每个部分的长度为 $\textit{cnt} + 1$,其余部分的长度为 。 接下来,我们只需要遍历链表,将链表分割成 个部分即可。

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 链表指针操作 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你一个头结点为 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 的字符串表示是 [] 。

示例 2:

输入:head = [1,2,3,4,5,6,7,8,9,10], k = 3
输出:[[1,2,3,4],[5,6,7],[8,9,10]]
解释:
输入被分成了几个连续的部分,并且每部分的长度相差不超过 1 。前面部分的长度大于等于后面部分的长度。

 

提示:

  • 链表中节点的数目在范围 [0, 1000]
  • 0 <= Node.val <= 1000
  • 1 <= k <= 50
lightbulb

解题思路

方法一:模拟

我们先遍历链表,得到链表的长度 nn,然后我们计算出平均长度 cnt=nk\textit{cnt} = \lfloor \frac{n}{k} \rfloor 和余数 mod=nmodk\textit{mod} = n \bmod k。那么对于前 mod\textit{mod} 个部分,每个部分的长度为 cnt+1\textit{cnt} + 1,其余部分的长度为 cnt\textit{cnt}

接下来,我们只需要遍历链表,将链表分割成 kk 个部分即可。

时间复杂度 O(n)O(n),空间复杂度 O(k)O(k)。其中 nn 为链表的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def splitListToParts(
        self, head: Optional[ListNode], k: int
    ) -> List[Optional[ListNode]]:
        n = 0
        cur = head
        while cur:
            n += 1
            cur = cur.next
        cnt, mod = divmod(n, k)
        ans = [None] * k
        cur = head
        for i in range(k):
            if cur is None:
                break
            ans[i] = cur
            m = cnt + int(i < mod)
            for _ in range(1, m):
                cur = cur.next
            nxt = cur.next
            cur.next = None
            cur = nxt
        return ans
speed

复杂度分析

指标
时间complexity is O(N) because each node is visited exactly once. Space complexity is O(1) aside from the output array, as the algorithm only manipulates pointers without allocating extra lists.
空间O(1)
psychology

面试官常问的追问

外企场景
  • question_mark

    Check if the candidate correctly handles empty nodes and k larger than list length.

  • question_mark

    Watch for proper pointer disconnection to avoid cycles or shared references between parts.

  • question_mark

    Look for correct distribution of extra nodes to the first N % k parts for balanced sizing.

warning

常见陷阱

外企场景
  • error

    Failing to account for N % k extra nodes can lead to uneven part sizes.

  • error

    Incorrectly reconnecting next pointers may merge parts or corrupt the list.

  • error

    Returning parts out of order instead of preserving the original sequence.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Split into parts but return sizes instead of the actual sublists for a memory-efficient check.

  • arrow_right_alt

    Split a doubly linked list maintaining both next and previous pointers correctly.

  • arrow_right_alt

    Split linked list in parts with additional constraint that no part can be empty unless necessary.

help

常见问题

外企场景

分隔链表题解:链表指针操作 | LeetCode #725 中等