zoukankan      html  css  js  c++  java
  • LeetCode725-Split Linked List in Parts-Medium

    分割链表

    题目:

    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, 
    oot.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个篮子里,每个篮子里的结点个数最多相差1. 并且前面的篮子结点数量要大于等于后面篮子的结点数量。
    会出现两种情况:
    1)篮子总数多于结点总数,则平均一个篮子里放一个结点,多出的篮子是空(null)。
    2)篮子总数少于结点总数。
    这两种情况可以总结成一个判断条件(见代码for语句)
     
    算法:
    1)遍历链表,得到结点总个数num。
    2)定义两个变量:avarage = num / k, residue = num % k:average是平均一个篮子放的结点数量,但是考虑到不会整除的情况,residue代表有多少个篮子需要放(average+1)个结点。
    3)进入for循环,i = 0, 循环退出的条件是遍历完整个数组(i < k && i < num), 即数组遍历完或结点遍历完。
      a) 先把当前结点放在result[i]中;
      b) 判断result[i]的链表长度(size), 并根据链表长度移动root指针。由于前面的篮子结点数量要大于后面篮子结点的数量,所以当residue>0时,size = (average+1), cur再向后移动average步,residue--。当residue减到0时,    size=average, cur再向后移动(average-1)步。此时root指向result[i]结点的尾部。
      c) result[i]链表中的最后一个结点指向null。(容易忘!)
      d) root结点向后移动一位。
    4)返回result数组。
     
    代码:
    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public ListNode[] splitListToParts(ListNode root, int k) {
            
            ListNode head = root;
            int num = 0;
            
            while(head != null){
                head = head.next;
                num++;
            }
            
            ListNode[] result = new ListNode[k];
            
            int average = num / k;
            int res = num % k;
            
            // traverse the result[] array to put ListNode in result[i]
            for(int i = 0; i < k && i < num; i++) {
                
                result[i] = root;
                
                int size = average + (res-- > 0 ? 1 : 0);
                /*
                int size = average;
                if(res > 0) {
                    size++;
                    res--;
                }
                */
                
                // 指针再向后移动(size-1)
                for(int j = 1; j < size; j++){
                    root = root.next;
                }
    // Remember to end this list! ListNode temp = root; root = root.next; temp.next = null; } return result; } }
     
     
     
  • 相关阅读:
    vb.net的数据类型
    PHP常用函数
    399. Evaluate Division
    329. Longest Increasing Path in a Matrix
    415. Add Strings
    463 Island Perimeter
    400. Nth Digit
    401. Binary Watch
    391. Perfect Rectangle
    406. Queue Reconstruction by Height
  • 原文地址:https://www.cnblogs.com/Jessiezyr/p/13082565.html
Copyright © 2011-2022 走看看