链表反转

反转全部

// 迭代
struct ListNode *reverseList(struct ListNode *head) {
struct ListNode *pre = NULL;
struct ListNode *next;
struct ListNode *cur = head; // 原地反转
while (cur != NULL) {
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
// 递归
struct ListNode *reverseList(struct ListNode *head) {
// 递归出口
if (head == NULL || head->next == NULL) return head;
// 递归式
struct ListNode *newHead = reverseList(head->next); // 递归反转后面的链表
head->next->next = head; // 下个结点也就是反转后的尾节点,指向自己
head->next = NULL; // 自己作为新的尾节点
return newHead;
}

反转前n个

// 第n个节点的直接后继
struct ListNode *successor = nullptr; // 反转前n个节点(递归)
struct ListNode *reverseListFront(struct ListNode *head, int n) {
if (head == nullptr || head->next == nullptr) return head;
if (n == 1) {
// 记录下原来顺序中第n+1个节点
successor = head;
return head;
} // 反转后面n-1个节点
ListNode *newHead = reverseListFront(head->next, n ### 1);
// 添加到反转后的n-1个节点的最后面
head->next->next = head;
// 反转全部链表时,这里是null;反转前n个时,这里是原链表中第n+1个节点
head->next = successor;
return newHead;
}

反转中间

// 反转[start, end],下标从1开始
struct ListNode *reverseListMid(struct ListNode *head, int start, int end) {
// 递归出口:反转前end个
if (start == 1) return reverseListFront(head, end);
// 递归体:反转以head.next为头节点的链表
head->next = reverseListMid(head->next, start ### 1, end ### 1);
}
struct ListNode *reverseBetween(struct ListNode *head, int left, int right) {
if (head == NULL || head->next == NULL || left >= right) return head;
// 虚拟头节点
struct ListNode *dummyHead = (struct ListNode *) malloc(sizeof(struct ListNode));
dummyHead->next = head;
struct ListNode *preNode = dummyHead;
int count = left - 1;
// preNode为left的直接前驱
while (count-- > 0) preNode = preNode->next;
// 暂存反转后的子链表的尾节点
struct ListNode *newTail = preNode->next; // 反转子链表
struct ListNode *pre = NULL, *next = NULL, *cur = preNode->next;
count = right - left + 1;
while (count-- > 0) {
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
// pre是right节点,即反转后子链表的头节点,next是原链表中right的直接后继
preNode->next = pre;
newTail->next = next;
return dummyHead->next;
}

链表反转(反转全部,前n个,中间)的更多相关文章

  1. 移除链表元素&反转链表&设计链表

    一.移除链表元素 203.移除链表元素 leetcode链接 1.方法概述 带傀儡节点的方法: 创建一个傀儡节点puppet来充当该链表的假头节点,当真正的头结点head不为null时,且在真正的头节 ...

  2. 代码随想录训练营day 4|链表基础理论,移除链表元素,设计链表,反转链表

    链表理论基础 链表是一种由指针串联在一起的线性结构,每一个节点都由一个数据域和一个指针域组成. 链表的类型有:单链表.双链表.循环链表. 链表的存储方式:在内存中不连续分布. 链表的定义很多人因为不重 ...

  3. 理解单链表的反转(java实现)

    要求很简单,输入一个链表,反转链表后,输出新链表的表头.   反转链表是有2种方法(递归法,遍历法)实现的,面试官最爱考察的算法无非是斐波那契数列和单链表反转,递归方法实现链表反转比较优雅,但是对于不 ...

  4. 秒懂单链表及其反转(reverse)

    什么是链表,这种数据结构是由一组Node组成的,这群Node一起表示了一个序列.链表是最普通,最简单的数据结构(物理地址不连续),它是实现其他数据结构如stack, queue等的基础. 链表比起数组 ...

  5. Java实现单链表的反转

    思路1:初始化一个新的头节点reverseHead,然后遍历旧链表,利用头插法向reverseHead进行插入 思路2: 1.反转相当于数据的更换(1和n,2和n-1,3和n-2)n为链表的长度 2. ...

  6. 【剑指Offer】【链表】反转链表

    题目:输入一个链表,反转链表后,输出新链表的表头. A:定义3个结点,pNode作移动指针,pRet作输出指针,pPrev作前驱指针    在pNode没有到达链尾之前,循环里创建pNext指针记录p ...

  7. 链表原地反转Demo

    现在就是Qt开发和给师弟师妹讲下数据结构吧,感觉还挺漫长的,上个Qt帖子等我把成品做出来再更. //Convert_plug.h #ifndef CONVERT #define CONVERT #de ...

  8. 【Leetcode链表】反转链表(206)

    题目 反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 进阶: 你可 ...

  9. 链表的反转、合并(不借助额外list数组)

    链表的基本操作:线性表 (单链表.循环链表-python实现) 反转链表: # -*- coding:utf-8 -*- class ListNode: def __init__(self, x): ...

  10. python 链表的反转

    code #!/usr/bin/python # -*- coding: utf- -*- class ListNode: def __init__(self,x): self.val=x self. ...

随机推荐

  1. chatgpt的api联网报错问题解决:openai公司的api联网报错解决

    chatgpt是啥,这里不讲,openai是啥这里也不讲.要知道我们不论是通过网页web使用chatgpt还是使用api方式通过客户端使用chatgpt都是需要使用外国IP的, 为啥我们不能访问ope ...

  2. 一款比较好用的 ssh、 ftp 服务的客户端软件 —— NxShell

    该软件地址: https://gitee.com/nxshell/nxshell 截图: ======================================================= ...

  3. Avnet ZUBoard 1CG开发板上手—深度学习新选择

    Avnet ZUBoard 1CG 开发板上手-深度学习新选择 摘要 本文主要介绍了 Avnet ZUBoard 1CG 开发板的特性.架构.硬件单元等概念,并对如何使用以太网接口和串口连接开发板进行 ...

  4. 第 111 场双周赛 - 力扣(LeetCode)

    第 111 场双周赛 - 力扣(LeetCode) 2824. 统计和小于目标的下标对数目 - 力扣(LeetCode) 枚举即可 class Solution { public: int count ...

  5. 为什么使用#define 而不是用enum定义常量

    typedef enum { IOTAG_PORT__A = (0), IOTAG_PORT__B, IOTAG_PORT__C, IOTAG_PORT__F, IOTAG_PORT__ITEMS } ...

  6. ARMv8-A 地址翻译技术之MMU的前世今生

    MMU的重要性不言而喻,支撑操作系统之上的各种复杂应用.但在正式讲MMU之前,我们先说说MMU的发展史,因为ARMv8-A的MMU相当复杂,直接切入正题,会显得比较枯燥.废话不多说,咱们马上开始: 一 ...

  7. .proto文件的作用

    在网络通信和通用数据交换等应用场景中经常使用的技术是 JSON 或 XML,而在最近的开发中接触到了 Google 的 ProtoBuf. 在查阅相关资料学习 ProtoBuf 以及研读其源码之后,发 ...

  8. elementui二维表动态渲染

    elementUI如何动态渲染二维表,动态渲染表格的列,例如下图: 代码: <div id="app"> <template> <el-table : ...

  9. 主观与客观,破除DDD凭经验魔咒

    本文书接上回<学习真DDD的最佳路径>,关注公众号(老肖想当外语大佬)获取信息: 最新文章更新: DDD框架源码(.NET.Java双平台): 加群畅聊,建模分析.技术实现交流: 视频和直 ...

  10. echarts的x轴显示不全的解决办法

    echarts的x轴显示不全的解决办法 一.背景 当x轴类目较多时,label显示时会自动间隔显示,也就是会隐藏掉中间的label,如下图: 二.解决办法 通过设置 xAxis.axisLabel.i ...