移除链表元素
题目链接:移除链表元素https://leetcode.cn/problems/remove-linked-list-elements/description/
先来看一下第一个题
画图更醒目,也叫画图分析代码逻辑,走读代码分析
把图文转换为代码如下,但还是有测试用例通不过,就拿测试用例思考一下
再来思考一下,前一篇中的单链表博客中,这种插入删除时传入的是二级指针,但这里使用的是一级指针,因为上一篇的函数为void,没有返回,想要改变一级指针就要传入一级指针的地址,但这个函数返回类型为结构体指针,最后return新的头节点就可以改变原来的链表。
再讲解另一种解法
可以看到还是有测试用例报错,简单想一下,如果尾节点也是要删除的数据,此时tail就是尾节点,需要把tail->next赋为NULL,但是再想一下,如果一开始就是一个空链表呢,tail是NULL就不能赋值了,所以最后也要判断一下,如果tail为NULL就证明是个空链表就不需要改变tail->next,如果不是就置为NULL。
那么到这里就讲完了这个题。
反转链表
题目链接:
反转链表https://leetcode.cn/problems/reverse-linked-list/description/
另一种方法
链表的中间节点
题目链接:
链表的中间节点https://leetcode.cn/problems/middle-of-the-linked-list/description/
链表中倒数第k个节点
题目链接:
虽然我们的思路没有问题,但最后还是报错了,那就来思考一下,题目里也没有说k一定小于等于链表个数的啊,那如果fast先走到NULL,比如链表有3个节点,想找到倒数第5个那肯定是不可能的啊,所以直接返会NULL就好了。
合并两个有序链表
题目链接:
合并两个有序链表https://leetcode.cn/problems/merge-two-sorted-lists/description/
又看到执行出错了,有特殊用例,如果一开始一个是空链表,就不会进入循环,直接来到下面,if语句判断的时候list1为空,不会进入这个语句,list2不为空,tail进行操作,但这时候太tail是NULL就会报错,就可以单独处理一下空链表的情况。
如果list1为空,就返回list2,如果list2为NULL,就返回list1,如果两个都是空链表,也没有问题,随便返回一个就可以。
上面这种是不带哨兵位的,那下面就写一个带哨兵位的。
malloc申请一块当作哨兵位,有了哨兵位就不用判断一开始是不是NULL了,最后再free掉哨兵位就可以了。
链表分割
题目链表:
题目解释的不是很清楚,那就画图来理解一下,假如x=7,就是如图这样变化的,不改变数据的顺序,也就是说头插不行,尾插也会很麻烦,那该怎样办呢。
虽然这里标注的是使用C++,但是C++兼容C,所以这里用C写是没有问题的。
可以是我们分析的没有问题,可是这里为什么会报错呢。
从这到就可以看到如果不带哨兵位,尾插时还需要处理NULL的情况,这也就是哨兵位的优势。
链表的回文
题目链接:
相交链表
题目链接:
相交链表https://leetcode.cn/problems/intersection-of-two-linked-lists/description/
第一种我们就不介绍了,我们来介绍另一种简单的思路
环形链表
题目链接:
环形链表https://leetcode.cn/problems/linked-list-cycle/description/
环形链表 ||
题目链表:
环形链表||https://leetcode.cn/problems/linked-list-cycle-ii/description/
在讲解这道题之前,我们先来证明一下为什么可以追上
走三步只是个问题的延申,为了拓展一下我们的思路,与这道题关联不大,接下来就来看一下这道题的思路,还是讨论快指针走两步的情况。
这里还有一个新思路
复制带随机指针的链表
题目链接:
复制带随机指针的链表https://leetcode.cn/problems/copy-list-with-random-pointer/description/
接下来我就来看一下这个复杂链表该如何去解,其实看这个题干还是很费劲的,我们解释一下,再来看这个示例。
这个尾插就没有使用哨兵位,那尾插就需要判断第一个节点是不是NULL。
那么这一篇文章就介绍到这里了,可以看到这些题都是单链表的,因为可以对于单链表的缺陷而出题,像双向带头循环链表的结构太完美了,出题感觉意义不大。写完了这一篇之后感觉自己对链表有了更深的理解,所以我们还是得努力,努力过后的那种充实的感觉让我回味无穷。
版权归原作者 微yu 所有, 如有侵权,请联系我们删除。