当前位置: 首页 > news >正文

【算法】725.分割链表--通俗讲解

一、题目是啥?一句话说清

给定一个链表和一个整数k,将链表分成k个连续部分,每部分长度尽可能相等(长度差不超过1),前面的部分长度要大于等于后面的部分。

示例:

  • 输入:head = [1,2,3,4,5,6,7,8,9,10], k = 3
  • 输出:[[1,2,3,4], [5,6,7], [8,9,10]]

二、解题核心

先计算链表总长度,确定每部分的基本长度和需要额外加1的部分数量,然后遍历链表进行分割。

这就像把一列人分成k个小组,先数总人数,然后计算每组大概多少人,尽量让每组人数差不多,前面组的人可以比后面组多一个。

三、关键在哪里?(3个核心点)

想理解并解决这道题,必须抓住以下三个关键点:

1. 计算链表总长度

  • 是什么:遍历整个链表,统计节点总数。
  • 为什么重要:只有知道总长度,才能合理分配每部分的长度。

2. 确定每部分的长度

  • 是什么:每部分基本长度 = 总长度 / k,前 (总长度 % k) 个部分长度加1。
  • 为什么重要:这确保了任意两部分长度差不超过1,且前面部分长度≥后面部分。

3. 链表分割操作

  • 是什么:遍历链表,根据计算出的长度切断链表,形成k个独立部分。
  • 为什么重要:这是实际执行分割的关键步骤,需要正确操作指针。

四、看图理解流程(通俗理解版本)

假设链表:1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10,k = 3

  1. 计算总长度:10个节点
  2. 计算每部分长度
    • 基本长度 = 10 / 3 = 3
    • 余数 = 10 % 3 = 1
    • 所以前1部分长度=4,后2部分长度=3
  3. 分割链表
    • 第一部分:取4个节点 [1,2,3,4]
    • 第二部分:取3个节点 [5,6,7]
    • 第三部分:取3个节点 [8,9,10]
  4. 结果:三个链表 [1→2→3→4], [5→6→7], [8→9→10]

五、C++ 代码实现(附详细注释)

#include <iostream>
#include <vector>
using namespace std;// 链表节点定义
struct ListNode {int val;ListNode *next;ListNode() : val(0), next(nullptr) {}ListNode(int x) : val(x), next(nullptr) {}ListNode(int x, ListNode *next) : val(x), next(next) {}
};class Solution {
public:vector<ListNode*> splitListToParts(ListNode* head, int k) {// 第一步:计算链表总长度int length = 0;ListNode* current = head;while (current != nullptr) {length++;current = current->next;}// 第二步:计算每部分的基本长度和需要额外加1的部分数量int base_size = length / k;    // 每部分的基本长度int extra = length % k;        // 需要额外加1的部分数量vector<ListNode*> result(k, nullptr); // 初始化结果数组current = head;// 第三步:分割链表for (int i = 0; i < k && current != nullptr; i++) {result[i] = current; // 记录当前部分的头节点// 计算当前部分的长度int part_size = base_size + (i < extra ? 1 : 0);// 移动到当前部分的末尾for (int j = 1; j < part_size; j++) {current = current->next;}// 切断链表,形成独立部分if (current != nullptr) {ListNode* next_part = current->next;current->next = nullptr;current = next_part;}}return result;}
};// 辅助函数:打印链表数组
void printParts(const vector<ListNode*>& parts) {for (int i = 0; i < parts.size(); i++) {cout << "Part " << i + 1 << ": ";ListNode* current = parts[i];while (current != nullptr) {cout << current->val << " ";current = current->next;}cout << endl;}
}// 测试代码
int main() {// 构建示例链表:1->2->3->4->5->6->7->8->9->10ListNode* head = new ListNode(1);ListNode* current = head;for (int i = 2; i <= 10; i++) {current->next = new ListNode(i);current = current->next;}Solution solution;vector<ListNode*> result = solution.splitListToParts(head, 3);printParts(result);// 释放内存for (ListNode* part : result) {while (part != nullptr) {ListNode* temp = part;part = part->next;delete temp;}}return 0;
}

六、时间空间复杂度

  • 时间复杂度:O(n),其中n是链表长度。需要遍历链表两次:一次计算长度,一次进行分割。
  • 空间复杂度:O(k),用于存储结果数组,k是分割的部分数。

七、注意事项

  • 空链表处理:如果链表为空,返回k个nullptr。
  • k大于链表长度:当k > length时,前length部分是单个节点,后面的都是nullptr。
  • 指针操作:在切断链表时,要确保正确设置next指针为nullptr。
  • 边界检查:在移动指针时要检查current是否为nullptr,避免空指针异常。
  • 内存管理:在C++中,分割后的链表需要分别管理内存。
  • 结果顺序:结果数组中的链表必须保持原链表的顺序。
http://www.dtcms.com/a/487876.html

相关文章:

  • 哈尔滨网站seowordpress域名设置
  • kettle Spoon 数据库连接步骤详解
  • 网站建设要做什么网站美化
  • Springboot——使用shyiko监听mysql的bin-log
  • 英特尔Day0适配Qwen3-VL-4B/8B新模型,释放系统资源带来流畅体验
  • 深度解析TENGJUN JA017-BPD105-A-SLIP-RING 10极滑动环耳机插座
  • 网站建设培训学校北京怎么做外网的网站
  • 东方网站建设展馆设计网站推荐
  • 做战袍网站贪玩手游官方网站
  • excel做注册网站网站被墙是谁做的
  • 河北省城乡建设培训网官方网站wordpress 在线文章插件
  • n8n飞书节点知识空间中的多维表格 Token如何获取
  • 做外贸的人经常逛的网站网校网站建设
  • LLVM IR深度技术解析:架构、优化与应用
  • 网站建设+三乐衡水景县专业做淘宝网站公司
  • linux学习笔记(33)网络编程——HTTP协议
  • 守护线程,礼让线程,插入线程
  • 网站建设好不好北京数据优化公司
  • 网站建设服务非常好湖南岚鸿公司万网怎样安装wordpress
  • FPGA职位经典笔/面试题(附答案与解析)
  • 哪个网站百度收录快怎样免费安装wordpress
  • 给客户做网站建设方案推广计划地域设置的作用描述不正确的是
  • N8N 系列:入门级,告别 SQL “天书”!N8N原生数据表 Data Tables,让新手也能轻松管理数据,上手即会用
  • 整体设计 逻辑系统程序 之28 拼语言+ CNN 框架核心定位、三阶段程序与三种交换模式配套的方案讨论 之1
  • 谷歌自建站和优化中国对外贸易公司排名
  • 网站被百度k掉怎么办手机网站制作方案
  • 永磁同步电机无速度算法--基于降阶准谐振ESO和Newton-Raphson方法PLL的PMSM无速度传感器控制
  • 网站建设推广方案策划书羽毛球赛事直播app
  • 做摄影网站的目的是什么给自己的网站做代言
  • GEO实战之GEO 在营销生态中的定位:GEO 与其他营销渠道的协同效应