zoukankan      html  css  js  c++  java
  • 分隔链表(力扣第725题)

    题目:

      给定一个头结点为 root 的链表, 编写一个函数以将链表分隔为 k 个连续的部分。每部分的长度应该尽可能的相等: 任意两部分的长度差距不能超过 1,也就是说可能有些部分为 null。这k个部分应该按照在链表中出现的顺序进行输出,并且排在前面的部分的长度应该大于或等于后面的长度。返回一个符合上述规则的链表的列表。

      举例: 1->2->3->4, k = 5 // 5 结果 [ [1], [2], [3], [4], null ]

    示例:

    输入: 
    root = [1, 2, 3], k = 5
    输出: [[1],[2],[3],[],[]]
    解释:
    输入输出各部分都应该是链表,而不是数组。
    例如, 输入的结点 root 的 val= 1, root.next.val = 2, 
    oot.next.next.val = 3, 且 root.next.next.next = null。
    第一个输出 output[0] 是 output[0].val = 1, output[0].next = null。
    最后一个元素 output[4] 为 null, 它代表了最后一个部分为空链表。

    分析:

      这个题最核心的部分就是根据k值与给定链表之间长度的比较结果,这里以length作为给定链表的长度选择对应的处理方式:

      k >= length时,结果数组的前length填写链表中的元素,每个数组元素都是单个的链表的结点,数组中剩下的值都为null

      k < length时,需要对链表的元素进行分组,此时结果数组的大小是固定的,即为k,那么我们需要将length个链表元素分成k组,而且要求任意两个部分长度差至多为1,并且是这k个部分是连续的,那可以这么做,首先先给每个部分分配相同数量指标,然后还会有剩余的数量指标,剩余的数量一定是小于k的,因为 length%k < k,那么根据任意两个部分长度差不能超过1的原则,就将这未分配的剩余数量指标,从左到右依次分配给每个部分,一个部分多出一个元素。每个部分的数量如下:

      length/k + 1,length/k + 1,length/k + 1,……,length/k   (加1的是前length%k个部分)

    代码实现:

    public ListNode[] splitListToParts(ListNode root, int k) {
            ListNode[] res = new ListNode[k];
            if (root == null){
                
                for (int i = 0; i < k; i++) {
                    res[i] = null;
                }
                return res;
            }
            ListNode p = root;
        
            int length = 0;
            while (p != null){
                
                length++;
                p = p.next;
            }
            p = root;
            if (k >= length){
    
                for (int i = 0; i < length; i++) {
                    
                    res[i] = new ListNode(p.val);
                    p = p.next;
                }
            }else {
                int[] part_nums = new int[k];
                Arrays.fill(part_nums,length/k);
    
                for (int i = 0; i < (length % k); i++) {
                    part_nums[i] = part_nums[i] + 1;
                }
                p = root;
                for (int i = 0; i < part_nums.length; i++) {
    
                    ListNode node = new ListNode(-1);
                    ListNode q = node;
                    for (int j = 0; j < part_nums[i]; j++) {
                        
                        ListNode node1 = new ListNode(p.val);
                        node1.next = q.next;
                        q.next = node1;
                        q = q.next;
                        p = p.next;
                    }
                    res[i] = node.next;
                }
            }
            return res;
        }

    我的代码有点垃圾,所以参考了cyc2018,我俩的思路是一样的,但是他在实现上彰显了大神的功力,即直接将原有的链表分隔成结果数组中的每个部分,学习一下:

    public ListNode[] splitListToParts(ListNode root, int k) {
         int N = 0;
        ListNode cur = root;
        while (cur != null) {
            N++;
            cur = cur.next;
        }
        int mod = N % k;
        int size = N / k;
        ListNode[] ret = new ListNode[k];
        cur = root;
        for (int i = 0; cur != null && i < k; i++) {
            ret[i] = cur;
            int curSize = size + (mod-- > 0 ? 1 : 0);
            for (int j = 0; j < curSize - 1; j++) {
                cur = cur.next;
            }
            ListNode next = cur.next;
            cur.next = null;
            cur = next;
        }
        return ret;
        }

    参考:

    https://github.com/CyC2018/CS-Notes/blob/master/notes/Leetcode%20%E9%A2%98%E8%A7%A3%20-%20%E9%93%BE%E8%A1%A8.md#9-%E5%88%86%E9%9A%94%E9%93%BE%E8%A1%A8

  • 相关阅读:
    BZOJ1527 : [POI2005]Pun-point
    2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
    2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)
    NAIPC-2016
    BZOJ2498 : Xavier is Learning to Count
    ACM ICPC Vietnam National Second Round
    XVI Open Cup named after E.V. Pankratiev. GP of Ukraine
    XVI Open Cup named after E.V. Pankratiev. GP of Peterhof
    HDU5509 : Pattern String
    BZOJ4583 : 购物
  • 原文地址:https://www.cnblogs.com/yxym2016/p/13402765.html
Copyright © 2011-2022 走看看