LeetCode每日一题(Split Linked List in Parts)

这篇博客介绍了如何使用递归方法将给定的单链表分成k个连续的部分,使得每个部分的长度尽可能相等。文章中提供了两种解决方案,包括将链表转换为节点数组再进行分组,以及直接使用递归实现。递归方法在保持链表原有顺序的同时,确保了部分之间的大小关系。给出了具体的Rust代码实现,并展示了示例输入和输出。
摘要由CSDN通过智能技术生成

Given the head of a singly linked list and an integer k, 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 one. This may lead to some parts being null.

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

Return an array of the k parts.

Example 1:

Input: head = [1,2,3], k = 5
Output: [[1],[2],[3],[],[]]

Explanation:
The first element output[0] has output[0].val = 1, output[0].next = null.
The last element output[4] is null, but its string representation as a ListNode is [].

Example 2:

Input: head = [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.

Constraints:

  • The number of nodes in the list is in the range [0, 1000].
  • 0 <= Node.val <= 1000
  • 1 <= k <= 50

两种方法:

  1. 先把链表拆成单个的 node 数组,然后分组,再组合
  2. 递归, 每次返回总数和当前 node 的序号,根据这两个判断当前是不是分组的头,然后做出相应的处理

第一种没什么技术含量,让我们来实现一下第二种


代码实现(rust):

impl Solution {
    fn rc(head: Option<Box<ListNode>>, k: i32, count: i32, parts: &mut Vec<Option<Box<ListNode>>>) -> (i32, i32, Option<Box<ListNode>>) {
        if let Some(mut h) = head {
            let next = h.next.take();
            let (total, num, p) = Solution::rc(next, k, count+1, parts);
            h.next = p;
            if total % k == 0 {
                if (num - 1) % (total / k) == 0 {
                    parts[((num - 1)/ (total / k)) as usize] = Some(h);
                    return (total, num-1, None);
                } else {
                    return (total, num-1, Some(h));
                }
            } else {
                let low = total / k;
                let high = low + 1;
                let remain = total % k;
                if num <= high * remain {
                    if (num - 1) % high == 0 {
                        parts[((num-1) / high) as usize] = Some(h);
                        return (total, num-1, None);
                    } else {
                        return (total, num-1, Some(h));
                    }
                } else {
                    if (num - remain - 1) % low == 0 {
                        parts[((num-remain-1) / low) as usize] = Some(h);
                        return (total, num-1, None);
                    } else {
                        return (total, num-1, Some(h));
                    }
                }
            }
        }
        return (count, count, None)
    }

    pub fn split_list_to_parts(mut head: Option<Box<ListNode>>, k: i32) -> Vec<Option<Box<ListNode>>> {
        if k == 1 {
            return vec![head];
        }
        let mut parts = vec![None; k as usize];
        Solution::rc(head, k, 0, &mut parts);
        parts
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值