725. Split Linked List in Parts。

Given a (singly) linked list with head node root, write a function to split the linked list into k consecutive linked list “parts”.

The length of each part should be as equal as possible: no two parts should have a size differing by more than 1. This may lead to some parts being null.

The parts should be in order of occurrence in the input list, and parts occurring earlier should always have a size greater than or equal parts occurring later.

Return a List of ListNode’s representing the linked list parts that are formed.

Examples 1->2->3->4, k = 5 // 5 equal parts [ [1], [2], [3], [4], null ]

Example 1:

Input:
root = [1, 2, 3], k = 5
Output: [[1],[2],[3],[],[]]
Explanation:
The input and each element of the output are ListNodes, not arrays.
For example, the input root has root.val = 1, root.next.val = 2, \root.next.next.val = 3, and root.next.next.next = null.
The first element output[0] has output[0].val = 1, output[0].next = null.
The last element output[4] is null, but it’s string representation as a ListNode is [].

Example 2:

Input:
root = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], k = 3
Output: [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]
Explanation:
The input has been split into consecutive parts with size difference at most 1, and earlier parts are a larger size than the later parts.


这题很长花了很久看题,但是看懂题目之后就好做了。题中的主要意思是给定一个链表和一个整数k,然后将这个链表分为k段,并且有限定条件:

1.如果链表的长度比k小就用null来补充。
就如给的例1一样,链表长度为3但是k的值为5,所以将链表分为5段时,节点不够,所以后面的都用null来表示。

2.如果链表不能平均分的时候,各段相差的节点数不能超过1,并且前面分段的要比后面的长。
就如给的例2一样,链表长度为10,分为3段,此时不能平均分配,各段相差的不能超过1并且前面分段的要比后面的长,所以就分为三段:[1,2,3,4]、[5,6,7]、[8,9,10]。

3.最后将每段组成一个链表,然后全部装进数组中返回。

按照这个算,如果给的链表长度是11然后k为3的话,分开之后就是:[1,2,3,4]、[5,6,7,8]、[9,10,11]。

看明白题之后就简单了,我们先对给定的链表求长度,然后除以k,会得到一个商和余数,商的数值代表平均分为k段之后每段有多少个节点,余数的数值代表前多少段需要多加一个节点,商和余数总共有以下几个情况:

(1)商为0,余数为0。

此时说明链表长度就是0,也不需要做什么处理,直接返回一个空数组就行。

(2)商为0,余数不为0。

说明此时的链表长度是小于k的,就如例1一样,商为0,余数为3。说明平均分为5段之后,平均每段有0个节点,然后前3段需要多加一个节点,那么正好就是:[1]、[2]、[3]、[]、[]。

(3)商不为0,余数为0。

说明此时正好能够将链表平均分为k段,每段的长度就是商的数值了。

(4)商不为0,余数不为0。

此时说明能将链表分为k段,但是还有多余的节点。而题中规定了各个分段的长度相差不能大于1,那么我们就只能让这多出的节点再次分给每段,而且每段只能分一个。并且题中还规定了前面的长度要比后面的常,所以我们就应该按照段的顺序再给分配一个了。需要注意这里的节点顺序不能乱。

比如题中的例2,长度为10,然后除以k之后得到商为3,余数为1。那么我们就知道平均分为3段之后,每段有3个节点,但是还多了一个节点,按照前面的要比后面的长的规则,只能将多出的节点放在第一段上。而且还要按照原来的顺序,所以我们先给第一段分了3个节点之后发现余数为1,我们需要将这1个节点再分给第一段,最后第一段就是[1,2,3,4],并且将余数减1说明没有多余的节点了。然后后面每段分配完3个节点之后发现余数为0,就代表没有多余的节点了再给他们了。

就好像万圣节发糖一样,我有10个糖,有3个小孩来要糖,我算了一下,每人能分3个糖,还多出一个糖,然后将这个糖奖励给了第一个小孩。

唯一不同的是我们需要注意原链表的顺序!


C++:

class Solution {
public:
    vector<ListNode*> splitListToParts(ListNode* root, int k) {
        vector<ListNode*> nodes;
        int counts = 0;//用来统计链表共有多少个节点
        ListNode* p = root;

        while(p) {//循环计算出总共的节点数
            p = p->next;
            counts++;
        }

        int num,rem,i,j;
        num = counts/k;//计算出每节有多少个固定节点
        rem = counts%k;//计算出余数,也就是前多少个段需要多一个节点

        for(i=0;i<k;i++) {
            ListNode* head = new ListNode(0);//新建一个新的头结点
            p = head;
            for(j=0;j<num;j++) {//每个节点的固定个数进行添加
                ListNode* node = new ListNode(root->val);
                p->next = node;
                p = p->next;
                if(root) {
                    root = root->next;
                }
            }
            if(rem-- > 0 && root) {//需要多加一个节点
                ListNode* rmnode = new ListNode(root->val);
                p->next = rmnode;
                if(root) {
                    root = root->next;
                }
            }

            nodes.push_back(head->next);//添加到数组中
        }

        return nodes;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值