[路飞]_leetcode刷题_725. 分隔链表

149 阅读2分钟

题目

725. 分隔链表

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

示例 2:

image.png

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

思路:

这题的思路其实没什么弯弯绕绕,正常分析就ok。

  1. 遍历链表,求出链表长度length
  2. 算出每个链表的基础长度 eachLength = Math.floor(length/k)
  3. 如果length/k除不尽,那么多出来的应该要分配给前面的部分,算出多出来的部分excess = length%k
  4. 遍历链表k次,则可将链表分成k份
  5. 遍历过程中,求出当前这一份的长度,这里就看当前是不是前excess份,是的话就 +1
  6. 然后再将cur节点向前推荐curLength-1次,这时候就是这一部分的末尾节点
  7. 如果末尾节点不是null,则做链表切断操作
  8. 最终返回数组result即可

代码:

/**
 * @param {ListNode} head
 * @param {number} k
 * @return {ListNode[]}
 */
var splitListToParts = function(head, k) {
    let cur = head;
    let length = 0;
    while(cur){
        cur = cur.next;
        length++;
    }
    let eachLength =  Math.floor(length/k);
    let excess = length%k;
    cur = head;
    let result = [];
    for(let i=0;i<k;i++){
        result[i] = cur;
        let curLength = eachLength + (i<excess?1:0);
        for(let j=1;j<curLength;j++){
            cur = cur.next;
        }
        if(cur){
            let tmp = cur.next;
            cur.next = null;
            cur = tmp;
        }
    }
    return result;
};