【链表题解】

1,反转链表

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

示例:

对于本题,采用头插法。

首先将head.next置为null。

定义一个cur和curN

将cur取出来头插到head位置前面,让他们建立联系(cur.next = head)

把cur给到head(head = cur),在让cur往后移(cur = curN)的同时curN向后移。

依次循环判断,当cur为null的时候,循环结束。

在循环之前要判断head是否为空,以防空指针异常。

2,链表的中间节点

题目描述:

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

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

示例:

对于本题,要使用双指针算法。

首先分别定义一个快,慢指针(fast,slow),同时指向head节点。

当慢指针走一步的同时,快指针走两步(slow = slow.next     fast = fast.next.next)。

一直走,走完整个链表发现

slow节点位置就是你所要找的节点,返回slow即可。观察尾节点奇数节点的循环结束条件为 fast.next==null,偶数节点的循环结束条件为 fast==null。

这里要注意while循环的条件,fast != null && fast.next != null 不可交换位置,否则会空指针异常!

3,返回倒数第k个节点

题目描述:实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。

示例:

说明:给定的 k 值是有效的

本题,要使用双指针算法。

首先分别定义一个快,慢指针(fast,slow),同时指向head节点。

让快指针(fast)走k-1步,比如k=3,让fast走两步

在让快指针和慢指针同时走,走到最后一个节点停下来

即slow位置就是我们所需要找的k节点位置,循环结束条件为fast.next == null,返回 slow.val 即可

4,合并两个有序链表

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

示例:

首先我们申请一个傀儡节点(newH),再用tmp来代替newH,用来拼接每一个节点,每次让headA和HeadB的val值进行比较,让最小的节点拼接到newH节点后面,若headA小于headB,就让tmp和headA进行拼接(tmp.next = headA),再让tmp指向headA节点,最后让headA移动到下一个节点。

若headA大于headB,则让tmp和headB进行拼接(tmp.next = headB),再让tmp指向headB节点,最后让headB移动到下一个节点。headA,B不为null即可循环。

当其中一条链表走完之后(可能是headA,可能是headB),比如headA链表走完了(headA == null),让tmp.next 指向headB即可(tmp.next = headB)即可连接。反之HeadB先走完,tmp.next 连接headA即可。

最后返回头节点,直接返回 newH.next。

5,判断是否为回文结构

描述:对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。

1,首先找到中间节点

使用双指针算法,定义一个fast,slow指针,slow走一步,fast走两步

2,反转中间节点后面的节点

定义一个cur表示slow节点的下一个节点,定义一个curN,记录cur节点的下一个节点

反转完之后,判断head的val是否等于slow的val。为什么不用fast往回走呢,因为在偶数个节点时,fast为空。

3,slow往前走,head往后走,直到相遇

首先head和slow不为空即可开始判断,判断head的val和slow的val是否相等,如果不相等,返回false,若相等,head和slow走向下一个即可。

但是我们发现,在偶数个节点时,此时的情况,head的下一个是slow,slow的下一个是0x78,这样就混乱了,在此时只需判断head的val和slow的val是否相等即可。

6,相交链表

描述:给你两个单链表的头节点headA 和 headB,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回null 。

示例:

两个来链表相交以后呈y字形

题目求的是黑色箭头所指的节点!!!

1,首先分别求出2个链表的长度,求出差值x

2,再让长的链表走x步

这里呢到底是headA长还是headB长,可以通过差值的正负数来判断谁长,若LenA(headA的长度)- LenB(headB的长度)为一个正数,则headA长,为负数则headB长

3,再一起走,直到相遇

注意红色框框,两个while循环走完后,pl和ps为null,若lenA与lenB的差值为正,不会走下面的if语句,判断while循环的时候,会导致 pl = pl.next 语句空指针异常(第三步)。即需要让pl和ps重新赋值!!!

但是后面要判断pl或者ps是否为null,若为null返回null。这里没有写但是没有报错,原因是因为第4步,如果其中一个为空,那么不会相交,pl和ps会一直走,走到链表完,即pl = null 和ps = null,然后会返回一个null。

7,环形链表 I

描述:给你一个链表的头节点head,判断链表中是否有环。

本题采用双指针算法来解决,从快慢指针上走,如果是存在环的情况下,他们一定会在环里面相遇(比如说,两个人A,B在操场跑步,如果A跑得快,B跑得慢,那么A和B总会相遇),如果不存在环,一个走得快,一个走得慢,那么永远相遇不了。

那么他们的速度是多少呢(也就是步数)?

我们让fast一次走两步,slow一次走一步!!!

问题:slow一次走一步,fast一次走三步可不可以?

答:不可以!!!如果这个环只有两个节点,在这种情况下,fast走三步,slow走一步,他们永远相遇不了。

那为什么fast一次走两步,slow一次走一步可以!这是一个数学问题。

最差最差情况下,fast走到一圈完的前面,slow刚进入环,也就是最大距离差一个环,每次fast走两步,slow走一步都在逼近,相当于每次追上一步,不会出现套圈的情况(slow走完一圈还没有相遇)。  如果步数差得多,就有可能会错过

8,环形链表 II

描述:若判断有环的情况下,找到环的入口节点,并打印这个节点的值

如果有环的情况下,fast和slow一定会在环里面相遇,我们把在环里面相遇的点叫做相遇点。

情况一:

我们设起始点到入口点的距离为x,再设环的长度为c,相遇点到入口点的距离为y。

情况二:

在此时的情况下,很明显x不等于y,就是说fast走到环里面后走了很多圈,一直在等slow过来

  • 23
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值