LeetCode之分隔链表

题目:

给定一个头结点为 root 的链表, 编写一个函数以将链表分隔为 k 个连续的部分。

每部分的长度应该尽可能的相等: 任意两部分的长度差距不能超过 1,也就是说可能有些部分为 null。

这k个部分应该按照在链表中出现的顺序进行输出,并且排在前面的部分的长度应该大于或等于后面的长度。

返回一个符合上述规则的链表的列表。

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


思路:

通过分析可知:

  • 如果k大于链表长度length,那么返回的数组的前length项的每个链表都只有一个结点,后面的 length+1 ~ k 项元素都是null;

    如1->2->3, k = 5,length = 3 ,则返回的数组中前3(length)个元素中的结点个数都是1个,4~5的数组索引中元素都为null。

  • 如果k小于链表长度length,那么返回的数组可以分成2个部分,前(length%k)项每个数组元素的链表中的结点数为 (length / k) + 1,后一部分的每个数组元素中的结点个数为(length/k)。

    如1->2->3->4->5,k = 2,length = 5;length / 2 = 2;length % 2 = 1。即返回的数组的前一部分(数组索引为1)有2+1个结点;后一部分(数组索引为1+1)有2个结点。


参考代码:

**打扫房间*
 public static ListNode[] splitListToParts(ListNode root, int k) {
      //** 注意root == null时是返回数组大小为k的null数组**//
       if(root == null || k <= 1)return new ListNode[k];
       //求链表的长度
       ListNode p = root;
       ListNode q;
       ListNode r;
       int length = 0;
       while(p != null){
         length ++;
         p = p.next;
       }
       ListNode[] listNode = new ListNode[k];
       //k>length,数组分成2部分,前length个元素中结点数为1,后一部分元素为null
       if(k > length){
           p = root;
           q = p;
           //前面k个数组元素都存一个节点
           for(int i = 0; i < length; i++){
           q = p.next;
           p.next = null;
           listNode[i] = p;
           p = q;
          
           }
       }
       //k<length,分成2部分,前length%k个元素中有length/k+1个结点,后一部分每个元素有length/k个元素
       else{
         int m = length % k;
            int n = length / k;
            p = root;
            q = root;
            //前m个链表有n+1结点,后边的链表都有n个结点
            int i = 0;
            while(p != null){
               //r记录头结点
               r = p;
               if(i < m){
                   for(int j = 0; j < n;j++)p = p.next;
               }
               else{
                   r = p;
                   for(int j = 0; j < n - 1; j++)p = p.next;
               }
               q = p.next;
               p.next = null;
               p = q;
               listNode[i] = r;
               i++;
            }
       }
   return listNode;
}

小结:

该题思路不难去想,但是在做的过程中还是要思路清晰,要把该注意的细节注意到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值