▶ 将一个单链表拆分为长度尽量接近的 k 段

● 自己的代码,12 ms

■ 记链表长度为 count,目标段数为 k,quo = count / k,mod = count % k,part = mod * (quo + 1)

■ 前半截(长半截)共有 mod 组,每组 quo + 1 个元素,共 mod * (quo + 1) 个元素,这是 part 的由来;后半截(长半截)共有 k - mod 组,每组 quo 个元素,共 quo * (k - mod) 个元素

■ 当 i < part 时,第 i 元素处于前半截,组号 s = i / (quo + 1),该组最后一个元素下标为 t = (quo + 1) * (s + 1) - 1,即满足 (t + 1) % (quo + 1) == 0

■ 当 i >= part 时,第 i 元素处于后半截,组号 s = (i - part) / quo + mod = (i - mod) / quo,该组最后一个元素下标为 t = (s + 1) * quo + mod - 1 (前面所有组的元素个数,注意偏移量 mod),即满足 (t + 1 - mod) % quo == 0

 class Solution
{
public:
vector<ListNode*> splitListToParts(ListNode* root, int k)
{
vector<ListNode *> table(k, nullptr);
if (root == nullptr)
return table;
int count, i;
ListNode *p, *q;
for (p = root, count = ; p->next != nullptr; p = p->next, count++);// 计算结点数
const int quo = count / k, mod = count % k, mod * (quo + );
for (p = table[] = root, i = ; p != nullptr && p->next != nullptr; i++)
{
if (i < part && !((i + ) % (quo + )))// p 指向了前半截某组的末尾结点
{
q = p->next, p->next = nullptr, p = q;
table[(i + ) / (quo + )] = q; // 注意此时是在table 中挂上 q 指向的结点,相当于第 i + 1 个结点
}
else if (i >= part && !((i + - mod) % quo))// p 指向了后半截某组的末尾结点
{
q = p->next, p->next = nullptr, p = q;
table[(i + - mod) / quo] = q;
}
else
p = p->next;
}
return table;
}
};

● 大佬的代码,11 ms,使用简单的判断 idx < remainder 来确认切分位置

 class Solution
{
public:
vector<ListNode*> splitListToParts(ListNode* root, int k)
{
if (k == )
return vector<ListNode*>{ root };
vector<ListNode*> res(k, nullptr);
ListNode *temp;
int len, idx, tmp;
for (len = , temp = root; temp != nullptr; len++, temp = temp->next);
const int per_len = len / k, remainder = len % k; for (idx = ; idx < k; )
{
tmp = per_len + (idx < remainder ? : );
if (tmp == )
{
res[idx++] = nullptr;
continue;
}
for (res[idx++] = root; tmp != ; root = root->next, tmp--);
temp = root->next, root->next = nullptr, root = temp;
} return res;
}
};

● 大佬的方法,11 ms,号称不需要知道链表的长度。每次指针 slow 移动一格,指针 fast 移动 k 格,直到 fast 抵达链表尾部,这时 slow 大约移动了 n / k 格,即为分界点。实际上 fast 在整个过程中移动了 O(n2) 的次数,还不如提前一趟遍历计算链表的长度

 class Solution
{
public :
vector<ListNode *> splitListToParts(ListNode *root, int k)
{
vector<ListNode *> res(k, nullptr);
ListNode *fast, *slow;
int i, step;
for (i = ; i < k; i++)
{
if (root == nullptr)
break;
for (slow = root, fast = root, step = k;;)
{
fast = move(fast, step);
if (fast != nullptr)
slow = slow->next;
else
break;
}
res[i] = root;
if (slow->next != nullptr)
{
root = slow->next;
slow->next = nullptr;
}
else
break;
step--;
}
return res;
}
ListNode* move(ListNode *node, int step)
{
for(;step > ;)
{
node = node->next;
step--;
if (node == nullptr)
break;
}
return node;
}
};

725. Split Linked List in Parts的更多相关文章

  1. LC 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 c ...

  2. 725. Split Linked List in Parts把链表分成长度不超过1的若干部分

    [抄题]: Given a (singly) linked list with head node root, write a function to split the linked list in ...

  3. #Leetcode# 725. Split Linked List in Parts

    https://leetcode.com/problems/split-linked-list-in-parts/ Given a (singly) linked list with head nod ...

  4. 【Leetcode】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 c ...

  5. LeetCode 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 c ...

  6. 【LeetCode】725. Split Linked List in Parts 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  7. Python解Leetcode: 725. Split Linked List in Parts

    题目描述:给定一个单链表,写一个函数把它分成k个单链表.分割成的k个单链表中,两两之间长度差不超过1,允许为空.分成的k个链表中,顺序要和原先的保持一致,比如说每个单链表有3个结点,则第一个单链表的结 ...

  8. LeetCode 725. Split Linked List in Parts(分隔链表)

    题意:将原链表分隔成k个链表,要求所有分隔的链表长度差异至多为1,且前面的链表长度必须大于等于后面的链表长度. 分析: (1)首先计算链表总长len (2)根据len得到分隔的链表长度要么为size, ...

  9. [leetcode]725. Split Linked List in Parts链表分块

    思路很简单  按时链表的题做起来很容易犯小错误,思维要缜密 还要多练习啊 做之前最好画算法框图 public ListNode[] splitListToParts(ListNode root, in ...

随机推荐

  1. Android中Tablayout设置下划线宽度 和 dp和px之间进行相互转换

    开发中遇到了一个问题,Tablayout设置下换线长度,看了点资料,分享给大家. 效果图:               直接贴代码(要在tabLayout添加完所有的tab后调用) public vo ...

  2. 10046event vs 10053event做了哪些操作

    10046 event 告诉我们oracle做了哪些事情,做的怎么样.10053 event 告诉我们oracle优化器怎么想的,再给出成本最低的最终的优化方案,考虑了哪些执行计划拿了哪些统计信息

  3. IOS-网络(NSURLSession)

    一.NSURLSession的基本用法 // // ViewController.m // NSURLSession // // Created by ma c on 16/2/1. // Copyr ...

  4. https ddos攻击——由于有了认证和加解密 后果更严重 看绿盟的产品目前对于https的ddos cc攻击需要基于内容做检测

    如果web服务器支持HTTPS,那么进行HTTPS洪水攻击是更为有效的一种攻击方式,一方面,在进行HTTPS通信时,web服务器需要消耗更多的资源用来进行认证和加解密,另一方面,一部分的防护设备无法对 ...

  5. SQLServer查看用户连接数

    SELECT login_name, ) user_count FROM Sys.dm_exec_requests dr WITH(nolock) RIGHT OUTER JOIN Sys.dm_ex ...

  6. 通过VNC连接远程服务器,然后登陆服务器上的虚拟机,出现键盘输入问题的解决方法

    前几天由于要在服务器上装一个虚拟机,然后就选择了vmware workstation,装好之后,进入虚拟机中的centOS系统,发现键盘上的Cpas Lock键不起作用,按下之后还是输入小写,而且按住 ...

  7. 理解 Socket

    原文链接 题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公司使用的一些控件的开发,浏览器兼容性搞死人 但主要是因为这段时间一直在看html5的东西,看到web socket ...

  8. 关于protel 99se 汉化后某些菜单消失的解决方法

    本人在使用protel 99se 画PCB时,遇到了好些问题,通过网上查资料基本都解决了. 下面给大家分享 关于protel 99se 汉化后某些菜单消失的解决方法. 其他的许多看不见的菜单也可以自己 ...

  9. Js 手风琴效果

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  10. 使用 Windows 10 中的加速度计(Accelerometer,重力传感器)

    在做 UWP 应用开发的时候还有什么理由可以用到加速度计呢?场景很多啦,比如做游戏,做类似 Surface Hub 那种一边旋转,一边所有内容跟着一起转的效果. Windows 10 UWP 中的加速 ...