反转链表、链表的中间结点、合并两个有序链表(leetcode 一题多解)

 一、反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

思路一:翻转单链表指针方向

这里解释一下三个指针的作用:

n1:记录上一个节点,如果是第一个就指向空

n2:记录此节点的位置

n3:记录下一个节点的位置,让翻转后能找到下一个节点,防止丢失指针的地址

/** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* reverseList(struct ListNode* head) {if(head == NULL){return NULL;}//初始条件struct ListNode* n1 = NULL,*n2 = head,*n3 = n2->next;//结束条件while(n2){//迭代过程n2->next = n1;n1 = n2;n2 = n3;if(n3)n3 = n3->next;}return n1;
}

思路二:头插法

取原链表节点头插到新链表

/** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* reverseList(struct ListNode* head) {struct ListNode* cur = head;struct ListNode* newHead = NULL;while(cur){struct ListNode* next = cur->next;//头插cur->next = newHead;newHead = cur;cur = next;}return newHead;
}

二、链表的中间结点

给你单链表的头结点 head ,请你找出并返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

思路一:单指针法

  • 时间复杂度:O(N*1.5),其中 N 是给定链表的结点数目。

  • 空间复杂度:O(1),只需要常数空间存放变量和指针。

我们可以对链表进行两次遍历。第一次遍历时,我们统计链表中的元素个数 N;第二次遍历时,我们遍历到第 N/2 个元素(链表的首节点为第 0 个元素)时,将该元素返回即可。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* middleNode(struct ListNode* head) {int n = 0;struct ListNode*cur = head;while(cur != NULL){++n;cur = cur->next;}int k = 0;cur = head;while(k < n/2){++k;cur = cur->next;}return cur;
}

思路二:快慢指针法

  • 时间复杂度:O(N),其中 N 是给定链表的结点数目。

  • 空间复杂度:O(1),只需要常数空间存放 slow 和 fast 两个指针。

我们可以优化思路一,用两个指针 slow 与 fast 一起遍历链表。slow 一次走一步,fast 一次走两步。那么当 fast 到达链表的末尾时,slow 必然位于中间。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* middleNode(struct ListNode* head) {struct ListNode* slow = head,*fast = head;while(fast && fast->next){slow = slow->next;fast = fast->next->next;}return slow;
}

三、合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

思路一(迭代法):

定义一个头指针和一个尾指针,从小到大依次尾插,直到一个链表为空时结束

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {if(l1 == NULL)    return l2;if(l2 == NULL)return l1;struct ListNode* head = NULL, *tail = NULL;while(l1 != NULL && l2 != NULL){if(l1->val < l2->val){//尾插if(tail == NULL){head = tail = l1;}else{tail->next = l1;tail = tail->next;}l1 = l1->next;}else{if(tail == NULL){head = tail = l2;}else{tail->next = l2;tail = tail->next;}l2 = l2->next;}}if(l1)tail->next= l1;if(l2)tail->next= l2;return head;
}

优化一:

先确定头结点,然后再循环判断val大小,尾插

struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {if(l1 == NULL)    return l2;if(l2 == NULL)return l1;struct ListNode* head = NULL, *tail = NULL;//先确定头节点if(l1->val < l2->val){head = tail =l1;l1 = l1->next;}else{head = tail =l2;l2 = l2->next;}while(l1 && l2){//尾插if(l1->val < l2->val){   tail->next = l1;l1 = l1->next;}else{tail->next = l2;l2 = l2->next;}tail = tail->next;}if(l1)tail->next= l1;if(l2)tail->next= l2;return head;
}

优化二:

设置一个哨兵位的头节点,然后再去尾插。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {if(l1 == NULL)    return l2;if(l2 == NULL)return l1;struct ListNode* head = NULL, *tail = NULL;//哨兵位的头节点head = tail = (struct ListNode*)malloc(sizeof(struct ListNode));while(l1 && l2){//尾插if(l1->val < l2->val){   tail->next = l1;l1 = l1->next;}else{tail->next = l2;l2 = l2->next;}tail = tail->next;}if(l1)tail->next= l1;if(l2)tail->next= l2;struct ListNode* first = head->next;free(head);return first;
}

思路二(递归法):

(这是题解中大佬的一个解法)以迭代的思路写递归,尤为惊人!!!

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){/*if判断:1.如果l1为空,返回l22.如果l2为空,返回l13.如果l1的值小于l2,比较l1的next值和l2,并把值赋给l1的下一个;返回l14.反之,比较l1和l2的next值,并把值赋给l2的下一个;返回l2*/if (l1 == NULL) {return l2;} else if (l2 == NULL) {return l1;} else if (l1->val < l2->val) {l1->next = mergeTwoLists(l1->next, l2);return l1;} else {l2->next = mergeTwoLists(l1, l2->next);return l2;}
}

因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。
如果不做,可能导致读写文件的问题。

今天就先到这了!!!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!

你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/583671.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在无公网IP环境下远程访问Serv-U FTP服务器共享文件

文章目录 1. 前言2. 本地FTP搭建2.1 Serv-U下载和安装2.2 Serv-U共享网页测试2.3 Cpolar下载和安装 3. 本地FTP发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 科技日益发展的今天&#xff0c;移动电子设备似乎成了我们生活的主角&#xff0c;智能…

英飞凌TC3xx之一起认识GTM系列(三)重点说一说GTM中断

英飞凌TC3xx之一起认识GTM系列(三)重点说一说GTM中断 GTM中断电平中断模式脉冲中断模式脉冲通知中断模式(常用)单脉冲中断模式GTM中断集中方法GTM中断对比GTM中断寄存器ATOM中断配置INT_TRIGxIRQ_NOTIFYIRQ_ENIRQ_FORCINTIRQ_MODETIM中断配置

Linux文件和目录管理命令---- tail 命令

Linux 中的 tail 命令是一个非常实用的工具,主要用于查看文本文件的最后部分。下面将详细介绍 tail 命令的不同用法 1. 基本用法 tail 命令最常见的用法是显示文件的最后几行。 命令: tail filename.txt结果: 这将显示 filename.txt 文件的最后 10 行。 2. 指定行数 可…

Java正则表达式

本文主要描述Java正则表达式&#xff08;Regular Expression&#xff09;&#xff0c;其作用是预先定义一个规则&#xff0c;然后&#xff0c;使用该规则匹配输入的字符串是否符合定义的规则&#xff0c;也可以从匹配的输出中提取字符串&#xff0c;正则表达式的常用使用场景包…

SSH是什么?有什么使用场景。

—ChatGPT-3.5 SSH&#xff08;Secure Shell&#xff09;是一种用于在网络上安全传输数据的协议。它主要用于在不安全的网络中提供加密的通信渠道&#xff0c;以防止窃听和数据篡改。SSH最初是为替代不安全的Telnet和FTP而设计的&#xff0c;但它现在被广泛用于安全地连接和管…

【Electron】富文本编辑器之文本粘贴

由于这个问题导致&#xff0c;从其他地方复制来的内容 粘贴发送之后都会多一个 换行 在发送的时候如果直接&#xff0c;发送innerHTML 就 可以解决 Electron h5 Andriod 都没问题&#xff0c;但是 公司的 IOS 端 不支持&#xff0c;且不提供支持&#xff08;做不了。&#xff…

UE5.1_移动端运行问题梳理

UE5.1_移动端运行问题梳理 目录 ue_移动端运行问题梳理 问题1.

Unity 旋转跟随

Unity 使用任意一个局部轴指向目标 效果&#xff1a; 主要用于在编辑器中可视化对象的朝向&#xff0c;同时提供了选择不同轴向的功能。在运行时&#xff0c;物体将根据所选择的轴向朝向目标&#xff0c;并在 Scene 视图中绘制一个带箭头的圆环。 定义轴向枚举&#xff1a;…

一起玩儿物联网人工智能小车(ESP32)——13. 用ESP32的GPIO控制智能小车运动起来(一)

摘要&#xff1a;本文更深入的讲述了GPIO的相关知识&#xff0c;并完成了导线连接工作&#xff0c;为下一步的软件开发做好了准备。 通用输入输出端口&#xff08;GPIO&#xff1a;General Purpose Input/Output Port&#xff09;&#xff0c;在前面已经有了初步的介绍&#xf…

三天吃透Spring面试八股文

目录&#xff1a; Spring的优点Spring 用到了哪些设计模式&#xff1f;什么是AOP&#xff1f;AOP有哪些实现方式&#xff1f;Spring AOP的实现原理JDK动态代理和CGLIB动态代理的区别&#xff1f;Spring AOP相关术语Spring通知有哪些类型&#xff1f;什么是IOC&#xff1f;IOC的…

flutter学习-day19-国际化支持

文章目录 1. 介绍2. 使用3. 获取当前区域Locale4. 监听语言切换5. 实现国际化5-1. 添加依赖5-2. 创建arb文件5-3. 添加provider状态管理5-4. 完成切换 本文学习和引用自《Flutter实战第二版》&#xff1a;作者&#xff1a;杜文 1. 介绍 默认情况下&#xff0c;Flutter SDK中的…

svn外网打不开url地址怎么解决

在家或者出差在外经常会有连接到公司内部SVN服务器的需求&#xff0c; 但是 svn外网打不开url地址怎么解决&#xff1f;如何才能连接到公司内部SVN服务器&#xff1f;今天小编教你一招&#xff0c;在本地SVN服务的内网IP端口用快解析软件添加映射&#xff0c;一步就可以提供让公…

Python模块、包与面向对象综合案例

Python模块、包与面向对象综合案例 一、Python内置模块 1、什么是Python模块 Python 模块(Module),是一个Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。模块能定义函数,类和变量,模块里也能包含可执行的代码。 2、模块的分类 在Python中,模块通常可…

TypeScript接口

1.TypeScript接口基本使用 声明接口需要使用 interface 关键字。 interface User {name: string;age: number; } 使用接口约束对象的类型。 const user: User {name: "张三",age: 20, }; 使用接口约束函数的类型。 interface Sum {(n: number, m: number): nu…

缺失的第一个正数(LeetCode 41)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路4.1 暴力4.2 排序4.3 哈希表4.4 空间复杂度为 O(1) 的哈希表4.5 置换 参考文献 1.问题描述 给你一个未排序的整数数组 nums &#xff0c;请你找出其中没有出现的最小的正整数。 请你实现时间复杂度为 O(n) 并且只使用常数级…

WPF Button使用漂亮 控件模板ControlTemplate 按钮使用控制模板实例及源代码 设计一个具有圆角边框、鼠标悬停时颜色变化的按钮模板

续前两篇模板文章 模板介绍1 模板介绍2 WPF中的Button控件默认样式简洁&#xff0c;但可以通过设置模板来实现更丰富的视觉效果和交互体验。按钮模板主要包括背景、边框、内容&#xff08;通常为文本或图像&#xff09;等元素。通过自定义模板&#xff0c;我们可以改…

会议室占用时间段 - 华为OD统一考试

OD统一考试 题解: Java / Python / C++ 题目描述 现有若干个会议,所有会议共享一个会议室,用数组表示各个会议的开始时间和结束时间, 格式为: [[会议1开始时间,会议1结束时间],[会议2开始时间,会议2结束时间]] 请计算会议室占用时间段。 输入描述 [[会议1开始时间,…

this和static和const关键字

1. this指针 1.1 基本认识 C中成员函数的特性&#xff0c;在类的非静态成员函数中都会存在一个this指针&#xff0c;来指向当前类&#xff0c;它是隐式的不可见的&#xff0c;是作为函数的第一个参数可以通过this指针来解决二义性的问题 是的&#xff0c;this指针是与类的实例相…

最快速度与最简代码搭建卷积神经网络,并快速训练模型,每日坚持手撕默写代码

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下最快速度与最简代码搭建卷积神经网络&#xff0c;并快速训练模型&#xff0c;每日坚持手撕默写代码。随着人工智能的快速发展&#xff0c;去年有强大的大模型ChatGPT横空出世&#xff0c;国内的大模型也紧追其后的发…

写一个java状态模式的详细实例

以下是一个示例的 Java 状态模式实现&#xff1a; java Copy code // 定义状态接口 interface State { void handleState(Context context); } // 具体状态类 1 class ConcreteState1 implements State { public void handleState(Context context) { System…