一日一连:分隔链表

125 阅读1分钟

给你一个头结点为 head 的单链表和一个整数 k ,请你设计一个算法将链表分隔为 k 个连续的部分。

思路

  • 获取链表总长度count
  • countk计算出每组需要放入的节点的平均数量,但是因为有可能有多余节点,所以前部分的数量可能比后面的数量多1。比如链表长度为10,分隔数量为3,每个组至少3个节点,但是因为多余1个,所以第一组的总数量为4个,要比其他组多1
  • 从链表头节点开始将链表分组,分组数量按2中得到的组数量分隔。这里需要注意的是,在得到特定数量节点的链表之后,要切掉尾结点与后一个节点的关联

代码

function splitListToParts(
  head: ListNode | null,
  k: number
): Array<ListNode | null> {
  let count = 0
  let cur = head
  while (cur) {
    count++
    cur = cur.next
  }
  // 每组至少节点数量
  const perNum = (count / k) >> 0
  // 比其他组要多1个节点的组的数量
  let moreItems = count % k
  const res = []
  cur = head
  // k组
  while (k-- > 0) {
    let currentListCount = perNum + (moreItems-- > 0 ? 1 : 0)
    // 特殊情况处理:组数量为0时,直接null
    if (currentListCount === 0) {
      res.push(null)
      continue
    }
    let pre = cur
    // 找到尾结点
    while (cur && --currentListCount > 0) {
      cur = cur.next
    }
    // 保存下一个节点,同时切掉与下一个节点的关联,以下个节点开始再次循环
    let next = cur.next
    cur.next = null
    cur = next
    res.push(pre)
  }
  return res
}