[路飞]_LeetCode_725. 分隔链表

76 阅读2分钟

题目

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

  示例 1:

image.png

输入:head = [1,2,3], k = 5
输出:[[1],[2],[3],[],[]]
解释:
第一个元素 output[0] 为 output[0].val = 1 ,output[0].next = null 。
最后一个元素 output[4] 为 null ,但它作为 ListNode 的字符串表示是 []

来源:力扣(LeetCode)leetcode-cn.com/problems/sp…

解题思路

  1. 遍历链表统计节点总数
  2. 总数除以k得出每组子链表的个数
  3. 总数 % k得出未除尽的节点数,把这些节点分到靠前的子链表中
  4. 通过for循环,循环k次,每次创建一个子链表,子链表的个数 = 每组个数 + 1 | 0
    • k 小于未除尽的节点数时 + 1
    • k 大于等于未除尽的节点数时 + 0
  5. 每组最后一个节点断开

代码实现

var splitListToParts = function(head, k) {
    //先统计链表的节点总数
    let count = 0
    let curr = head

    while(curr) {
        curr = curr.next
        count++
    }

    curr = head
    //计算每组大小
    const groupSize = Math.floor(count / k)
    
    //计算多出来的部分,分到靠前的组里
    let overflow = count % k
    const res = new Array(k).fill(null)

    for (let i = 0; i < k && curr !== null; i++) {
        res[i] = curr
        let subListSize = groupSize + (i < overflow ? 1 : 0)
        for (let j = 1; j < subListSize; j++) {
            curr = curr.next
        }

        //端口子链表
        const next = curr.next
        curr.next = null
        curr = next
    }

    return res
};

如有错误欢迎指出,欢迎一起讨论!