链表反转(反转全部,前n个,中间)
链表反转
反转全部
// 迭代
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个,中间)的更多相关文章
- 移除链表元素&反转链表&设计链表
一.移除链表元素 203.移除链表元素 leetcode链接 1.方法概述 带傀儡节点的方法: 创建一个傀儡节点puppet来充当该链表的假头节点,当真正的头结点head不为null时,且在真正的头节 ...
- 代码随想录训练营day 4|链表基础理论,移除链表元素,设计链表,反转链表
链表理论基础 链表是一种由指针串联在一起的线性结构,每一个节点都由一个数据域和一个指针域组成. 链表的类型有:单链表.双链表.循环链表. 链表的存储方式:在内存中不连续分布. 链表的定义很多人因为不重 ...
- 理解单链表的反转(java实现)
要求很简单,输入一个链表,反转链表后,输出新链表的表头. 反转链表是有2种方法(递归法,遍历法)实现的,面试官最爱考察的算法无非是斐波那契数列和单链表反转,递归方法实现链表反转比较优雅,但是对于不 ...
- 秒懂单链表及其反转(reverse)
什么是链表,这种数据结构是由一组Node组成的,这群Node一起表示了一个序列.链表是最普通,最简单的数据结构(物理地址不连续),它是实现其他数据结构如stack, queue等的基础. 链表比起数组 ...
- Java实现单链表的反转
思路1:初始化一个新的头节点reverseHead,然后遍历旧链表,利用头插法向reverseHead进行插入 思路2: 1.反转相当于数据的更换(1和n,2和n-1,3和n-2)n为链表的长度 2. ...
- 【剑指Offer】【链表】反转链表
题目:输入一个链表,反转链表后,输出新链表的表头. A:定义3个结点,pNode作移动指针,pRet作输出指针,pPrev作前驱指针 在pNode没有到达链尾之前,循环里创建pNext指针记录p ...
- 链表原地反转Demo
现在就是Qt开发和给师弟师妹讲下数据结构吧,感觉还挺漫长的,上个Qt帖子等我把成品做出来再更. //Convert_plug.h #ifndef CONVERT #define CONVERT #de ...
- 【Leetcode链表】反转链表(206)
题目 反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 进阶: 你可 ...
- 链表的反转、合并(不借助额外list数组)
链表的基本操作:线性表 (单链表.循环链表-python实现) 反转链表: # -*- coding:utf-8 -*- class ListNode: def __init__(self, x): ...
- python 链表的反转
code #!/usr/bin/python # -*- coding: utf- -*- class ListNode: def __init__(self,x): self.val=x self. ...
随机推荐
- 强化学习:reward function shaping —— 着陆器(lander)游戏中的奖励函数的设计
lander 游戏是强化学习问题中常使用的一个游戏场景,不同人对该问题都设置了不同的reward function,一直也没有对该游戏的各种reward function的设计做一个记录,正好看视频看 ...
- 说说中国高校理工科教育中的基础概念混乱问题——GPU是ASIC吗
在YouTube上看到这样一个视频: https://www.youtube.com/watch?v=7EXDp6c9n-Q&lc=Ugydwl8gppB5FWE8Y5V4AaABAg.9fc ...
- C#.Net筑基-解密委托与事件
委托与事件是C#中历史比较悠久的技术,从C#1.0开始就有了,核心作用就是将方法作为参数(变量)来传递和使用.其中委托是基础,需要熟练掌握,编程中常用的Lambda表达式.Action.Func都是委 ...
- npm WARN config global `--global`, `--local` are deprecated. Use `--location 的解决方法
1.背景 2.解决步骤 2.1.找到nodejs的安装路径 2.2.修改配置文件 将文件里的 prefix-g 改为 prefix --location=global 修改前: 修改后: 点击保存就解 ...
- 题解:CF780B The Meeting Place Cannot Be Changed
这道题一看就是 二分 板子题. 当然由于精度原因,最好由原来的二分模板转换成这个. while ((w - t) > 0.000001) { mid = (t + w) / 2.0 ; if ( ...
- 知攻善防Web1应急靶机笔记--详解
知攻善防Web1应急靶机笔记 概述 这是一台知攻善防实验室的应急响应靶机,方便大家练习一下应急响应的流程和操作. 靶机的前景概述: 前景需要: 小李在值守的过程中,发现有CPU占用飙升,出于胆子小,就 ...
- MFC实现屏幕截屏
屏幕截屏 void CMainFormDlg::GetScreenPic(Rect area, OUT Mat &img, float rate, bool gray) { CDC *pDC ...
- 优化系统性能:深入探讨Web层缓存与Redis应用的挑战与对策
Web层缓存对于提高应用性能至关重要,它通过减少重复的数据处理和数据库查询来加快响应时间.例如,如果一个用户请求的数据已经缓存,服务器可以直接从缓存中返回结果,避免了每次请求都进行复杂的计算或数据库查 ...
- springcloud feign集成hystrix
本章介绍feign集成hystrix 1.增加pom依赖` <dependency> <groupid>org.springframework.cloud</groupi ...
- 从0写一个电话号码管理的C入门项目【适合初学者】
0.前言 上次发了一个嵌入式的学习路线,很多粉丝问我各个阶段的入门项目,其中第二阶段的<基于socket聊天室>写了4篇循序渐进的文章,而第一阶段的<电话号码本管理>也非常想要 ...