【LeetCode】【数据结构】单链表OJ常见题型(一)

news2024/11/25 0:29:04

 👀樊梓慕:个人主页

 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》

🌝每一个不曾起舞的日子,都是对生命的辜负。


目录

前言:

【LeetCode】203.移除链表元素

【LeetCode】206.反转链表

 思路一

思路二

【LeetCode】876.链表的中间结点

快慢指针法

【LeetCode】剑指Offer 22.链表中倒数第k个结点

快慢指针法 

【LeetCode】21.合并两个有序链表

【LeetCode】剑指Offer Ⅱ 27.回文链表


前言:

本系列博文博主会讲解链表的经典OJ题目。

欢迎大家📂收藏📂以便未来做题时可以快速找到思路,巧妙的方法可以事半功倍。

=========================================================================

GITEE相关代码:🌟fanfei_c的仓库🌟

=========================================================================

【LeetCode】203.移除链表元素

原题链接:🍏移除链表元素🍏

题目:给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

 要想删除当前元素,需要知道当前元素的位置,及前一个元素的位置,并且保存下一个元素的位置。

所以我们需要三个指针:

  • 一个指针命名为cur,作用是遍历;
  • 一个指针命名为prev,指向位置为cur的前一个位置,作用是删除(prev->next=cur->next);
  • 一个next指针用来保存cur的后一个位置,确保free掉cur后仍然可以找到下一元素。

代码实现: 

/*
解题思路:从头节点开始进行元素删除,每删除一个元素,需要重新链接节点
*/
struct ListNode* removeElements(struct ListNode* head, int val) {
    if(head == NULL)
        return NULL;
    
    struct ListNode* cur = head;
    struct ListNode* prev = NULL;
    
    while(cur)
    {
        //如果当前节点是需要删除的节点
        if(cur->val == val)
        {
            //首先保存下一个节点
            struct ListNode* next = cur->next;
            //如果删除的为头节点,更新头节点
            //否则让当前节点的前趋节点链接next节点
            if(prev == NULL)
            {
                head = cur->next;
            }
            else
            {
                prev->next = cur->next;  
            }
            //释放当前节点,让cur指向next
            free(cur);
            cur = next;
        }
        else
        {
            //如果cur不是需要删除的节点,则更新prev,cur
            prev = cur;
            cur = cur->next;
        }
    }
    
    return head;
}

注意:考虑极端情况,如首个位置就是val的情况,作单独处理。


【LeetCode】206.反转链表

原题链接:🍏反转链表🍏

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

​ 

 思路一

同样的我们需要三个指针来完成这一操作:

  • 一个指针命名为cur,作用是遍历;
  • 一个指针命名为prev,作用是拿到cur的前一个地址,而后改变cur->next指向prev;
  • 一个指针命名为next,作用是保存cur的后一个位置,防止修改cur->next后找不到cur的后一个位置。

代码实现:

struct ListNode* reverseList(struct ListNode* head)
{
	struct ListNode* prev = NULL;
	struct ListNode* cur = head, * next = head;
	
	if (cur)// 检查cur是否为空
	{
		next = cur->next;
	}
	while (cur)
	{
        // 往后走
		prev = cur;
		cur = next;
		
        if(next)// 检查next是否为空
			next = next->next;
	}
	return prev;
}

思路二

取结点头插,完成逆置。

大家只要掌握了头插就很简单了。

代码实现:

// 取节点头插的思想完成逆置
struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode* newhead = NULL;
    struct ListNode* cur = head;
    while(cur)
    {
        struct ListNode* next = cur->next;
        //头插新节点,更新头
        cur->next = newhead;
        newhead = cur;
        cur = next;
    }
    
    return newhead;
}

【LeetCode】876.链表的中间结点

原题链接:🍏链表的中间结点🍏

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

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

快慢指针法

若想找到中间结点,我们可以定义两个指针:

  • 一个命名为slow,令slow每次走一步;
  • 一个命名为fast,令fast每次走两步。

这样当fast为NULL,或fast->next为NULL时,slow恰好处于中间位置,最后返回slow即可。

代码实现:

struct ListNode* middleNode(struct ListNode* head)
{
    struct ListNode* slow=head;
    struct ListNode* fast=head;
    while(fast && fast->next)// 分别为奇数个与偶数个的判断条件
    {
        slow=slow->next;
        fast=fast->next->next;
    }
    return slow;
}

【LeetCode】剑指Offer 22.链表中倒数第k个结点

原题链接:🍏链表中倒数第k个结点🍏

题目:输入一个链表,输出该链表中倒数第k个节点。

快慢指针法 

同样需要快慢指针的方法。

令fast先走k步,slow不动,然后slow与fast同时向后走,直到fast为NULL,此时slow的位置就是倒数第k个位置。

代码实现:

struct ListNode* getKthFromEnd(struct ListNode* head, int k)
{
    struct ListNode* slow=head,* fast=head;
    
    while(k--)
    {
        if(fast==NULL)
        {
            return NULL;
        }   
        fast=fast->next;
    }
    
    while(fast)
    {
        slow=slow->next;
        fast=fast->next;
    }
    
    return slow;
}

【LeetCode】21.合并两个有序链表

原题链接:🍏合并两个有序链表🍏

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

 思路:取小的尾插。

 注意:极端情况的判断,如其中一个链表为空等等。

代码实现: 

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
    if(list1==NULL)// 判断其中一个链表为空的情况
    {
        return list2;
    }
    if(list2==NULL)// 判断其中一个链表为空的情况
    {
        return list1;
    }
    struct ListNode* head=NULL,*tail=NULL;
    while(list1 && list2)
    {
        if(list1->val<list2->val)
        {
            if(head==NULL)// 头结点直接赋值
            {
                head=tail=list1;
            }
            else// 尾插
            {
                tail->next=list1;
                tail=tail->next;
            }
            list1=list1->next;
        }
        else
        {
            if(head==NULL)// 头结点直接赋值
            {
                head=tail=list2;
            }
            else// 尾插
            {
                tail->next=list2;
                tail=tail->next;
            }
            list2=list2->next;
        }
    }
    if(list1)// list1有剩余
    {
        tail->next=list1;
    }
    if(list2)// list2有剩余
    {
        tail->next=list2;
    }
    return head;
}

【LeetCode】剑指Offer Ⅱ 27.回文链表

原题链接:🍏回文链表🍏

题目:给定一个链表的 头节点 head ,请判断其是否为回文链表。

如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。

 思路:找到中间结点,将后半部分逆置,最后令前后两部分一一对比,如果结点的值全部相同,则为回文。

 刚好我们可以利用上面实现过的函数:链表的中间结点和反转链表。

代码实现:

// 找到中间结点
struct ListNode* middleNode(struct ListNode* head)
{
   struct ListNode* slow = head;
   struct ListNode* fast = head;
   while (fast && fast->next)
   {
       slow = slow->next;
       fast = fast->next->next;
   }
   return slow;
}

// 反转一个单链表
struct ListNode* reverseList(struct ListNode* head)
{
   struct ListNode* tail = NULL;
   struct ListNode* cur = head, * next = head;
   while (next)
   {
       next = cur->next;
       cur->next = tail;
       tail = cur;
       cur = next;
   }
   return tail;
}

// 判断回文结构
bool isPalindrome(struct ListNode* head)
{
    struct ListNode* mid=middleNode(head);
    struct ListNode* newhead=reverseList(mid);
    while(head && newhead)
    {
        if(head->val!=newhead->val)
        {
            return false;
        }
        else
        {
            head=head->next;
            newhead=newhead->next;
        }
    }
    return true;
}

 =========================================================================

如果你对该系列文章有兴趣的话,欢迎持续关注博主动态,博主会持续输出优质内容

🍎博主很需要大家的支持,你的支持是我创作的不竭动力🍎

🌟点赞收藏+关注 ~🌟

========================================================================= 

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

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

相关文章

不同语言操作符的优先级

看到标题&#xff0c;可能会心生疑惑: 这么基础且重要的操作&#xff0c;不同语言不应该是一致的吗&#xff1f; 并不一定&#xff0c;比如对于右移运算和加法运算&#xff0c;Go就与其他多数语言表现得不一致&#xff1a; Go: package mainimport "fmt"func main() …

解密Redis:应对面试中的缓存相关问题

文章目录 1. 缓存穿透问题及解决方案2. 缓存击穿问题及解决方案3. 缓存雪崩问题及解决方案4. Redis的数据持久化5. Redis的过期删除策略和数据淘汰策略6. Redis分布式锁和主从同步7. Redis集群方案8. Redis的数据一致性保障和高可用性方案 导语&#xff1a; 在面试过程中&#…

社区说|Flutter 一知半解,带你拨云见月

Hello&#xff0c;大家好&#xff0c;我是 Flutter GDE 郭树煜&#xff0c;今天的主题是科普向的分享内容&#xff0c;主要是带大家更全面的去理解 Flutter &#xff0c;尽可能帮助大家破除一些误解&#xff0c;分享内容不会特别长&#xff0c;但是应该会帮助你从新认识下 Flut…

C++源码使用make生成动态库和静态库

我这个新电脑&#xff0c;没装Homebrew&#xff0c;把这个复制进终端安装。 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 下载过程如下所示

blender凹凸感和置换形变

一、怎么做出凹凸感 需要三个部分的内容&#xff1a; 1、一个基础的纹理&#xff1a;告诉计算机需要用一个什么样的纹理做凹凸&#xff0c;纹理一般采用黑白&#xff0c;在计算机里面&#xff0c;从 0 - 1之间的值可以用从黑到白之间不同的灰度来表示因此&#xff0c;有一张黑白…

char类型到底是有符号还是无符号的?

最近在整理代码时&#xff0c;发现有一些如下类型的警告&#xff1a; ..\XXXXX\XXXXX.c(224): warning: #186-D: pointless comparison of unsigned integer with zero 这个警告的意思是无符号数与0比较是无意义&#xff0c;而我报警告的代码行如下&#xff1a; char len_v…

阿里用户序列建模ETA

End-to-End User Behavior Retrieval in Click-Through Rate Prediction Model 摘要 现实很少有工作可以处理长序列用户建模的问题&#xff0c;SIM提出了两阶段方法。第一阶段&#xff0c;辅助任务旨在从长序列用户行为检索最相关的用户行为序列。第二阶段&#xff0c;经典的…

位图和 DC 有什么特别之处?

相信设备上下文 (DC, Device Context) 对你来说&#xff0c;应该很熟悉。 基本工作方式是&#xff0c;你可以通过调用 SelectObject 来将画笔(Pen)&#xff0c;画刷(Brush)&#xff0c;字体(Font)和位图(Bitmap)等这些对象选入设备上下文中&#xff0c;但是&#xff0c;这里的位…

Android 面试题 应用程序结构 十一

&#x1f525; Framework主要包含以下模块 &#x1f525; ActivityManagerService 这是一个Activity的管理者&#xff0c;负责管理所有Activity的生命周期。WindowManagerService 它是手机屏幕的的管理者&#xff0c;管理着屏幕的详细情况&#xff0c;所有对屏幕的操作最终都…

ChatGPT学python——制作自己的AI模型(一)初步了解

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★前端炫酷代码分享 ★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ 解决算法&#xff0c;一个专栏就够了★ ★ 架…

2023国际先进制造青年科学家大会圆满结束!易知微受邀进行数字孪生主题报告分享

2023年7月30日&#xff0c;以“新青年&#xff0c;新视野&#xff0c;新制造”为主题的2023国际先进制造青年科学家大会在浙江绍兴开幕&#xff0c;旨在强力推进创新深化改革攻坚开放提升&#xff0c;进一步做强“人才&#xff0b;产业”双联驱动、人才集聚与产业发展共振同兴&…

NLP/CV相关模型库-阿里

模型库地址&#xff1a;https://www.modelscope.cn/models

30岁转行学编程,更容易成功

“男人30而立&#xff0c;我没有退路&#xff0c;只有选择勇往直前&#xff0c;这样我才能无所畏惧&#xff0c;因为我希望在我的人生篇章里&#xff0c;能拥有浓墨重彩的一笔&#xff01;” 30岁&#xff0c;在经历一番“打击”后毅然决然选择学编程&#xff0c;为家人也为自…

解决Mysql报错2003 (HY000): Can‘t connect to MySQL server on ‘localhost‘ (10061)

1.找到mysql文件夹&#xff0c;将my,ini文件放入bin文件夹 2.管理员模式打开cmd 3.输入netstat -ano查看端口占用情况&#xff0c;这里我已经开启mysql应用&#xff0c;所以会有3306&#xff0c;如果没有开启是不会有的 4.输入sc delete mysql&#xff0c;删除mysql服务 5.将…

Vue如何实现重定向

在刚登录之后&#xff0c;我们想要默认展示一下用户登录&#xff0c;这个功能如何实现&#xff1a; 就是重定向为/home/user这个值 我们就是在/home 上加一个重定向 具体怎么做那&#xff0c;先找到/home的路由规则 想要实现重定向,增加一个redirect就行

基于SpringBoot+Vue的广场舞团管理系统设计与实现(源码+LW+部署文档等)

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

无涯教程-Lua - 环境安装

在Windows上安装 为Windows环境开发了一个单独的名为" SciTE"的IDE,可以从https://code.google.com/p/luaforwindows/下载部分。 运行下载的可执行文件以安装Lua IDE。 由于它是一个IDE&#xff0c;因此您可以使用它来创建和构建Lua代码。 如果您有兴趣在命令行模…

【私藏】matlab踏实手把手常规练习附全套学习资料

目录 前言 福利&#xff1a;文末有matlab全套资料哦 01分段函数 02复合图 ⚪️ 两个一元函数yx^3-x-1和y|x|^(0.2)sin(5x)在区间-1<2的复合图。函数与图像<> 03三维平面图 ⚪️ 三维平面图使用mesh绘制网格图&#xff0c;surf绘制三维曲面图&#xff0c;使用…

filebeat kibana elasticsearch 日志监控

解压三个压缩包 一、filebeat的安装部署 1、打开filebeat的配置文件 2、Filebeat inputs 处打开日志输入开关&#xff0c;设置要监控的路径 3、Outputs 输出中设置Elasticsearch output的输出地址 4、执行 ./filebeat & 二、Elasticsearch 安装部署 1、修改配置文件 …

C语言:相交链表

Lei宝啊&#xff1a;个人主页 愿美好与我们不期而遇 题目&#xff1a; 描述 给你两个单链表的头节点 headA和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 接口 struct ListNode *getIntersectionNode (str…