单链表经典算法题

一:反转链表:

  206. 反转链表 - 力扣(LeetCode)

思路一:就是创建一个新的链表,然后将原链表的节点拿过来头插:

首先创建一个新的链表(带头链表)(哨兵位)然后每次在每次循环旧链表时,创建一个新的节点,将旧链表中存储的值给新的节点,再让新的节点头插到新的链表中即可。

创建如图所示的所需要的内容:

这个就是这个思路的准备工作。

现在开始循环旧链表,将旧链表的值赋给每次循环创建的新节点。

这就是循环里的一次过程。

接下来就是整个循环的代码:

整个代码如图:

在这里即使旧链表为空,这个代码也符合,当旧链表为空时,不会进入这个循环,所以创建的新链表也为空,此时返回新链表的第一个有效节点即为空。

思路二:创建三个指针,来完成链表的翻转

创建n1,n2,n3三个指针,n3指向旧链表的第二个节点,n2指向旧链表的第一个节点,n1先置为空指针。

这样基本工作就准备完成了。

接下来,首先n2->next指向n1,再让n1移动到n2的位置,n2移动到n3的位置,n3往后移动,最后当n2为空时就停止循环。图解如下:

这是起始位置,现在演示循环一次,如图:

这就是循环一次的结果,这样就翻转过来了。

当n2是空指针时循环就可以停止了,再返回n1的位置这样整个代码基本就实现了

代码实现:

但是这个代码被报错了,因为我们没有考虑到链表为空的情况,当前链表为空的话,你对其进行解引用这就会报错了,所以我们要加上链表为空的情况。

此时的代码就正确了。

总结:思路二的好处是没用创建额外的空间进行解题,这样使得代码更加高效。当面试时要求不能创建额外空间解题时,思路一就用不了了。

二:移除链表元素:

203. 移除链表元素 - 力扣(LeetCode)

思路一:创建一个新链表,然后遍历旧链表,再将旧链表中值不为val的尾插到新链表中:

创建一个指针用来遍历旧的链表,再创建一个新的链表,newHead用来记录新链表的第一个节点的位置,newTail用来参与尾插的移动。

当pcur为空时就代表旧的链表已经走完。

先判断是否为空链表,如果为空链表则pcur即为新链表的头也为尾,最后返回链表的头即可。

如果不为空链表则尾插不为其值的元素

最后当旧链表遍历完如果newtail不为空就手动将其下一个节点置为空。

思路二:遍历原链表,将原链表节点为val的值给释放掉:

先创立两个指针都指向头节点,然后n2先走去找到要删除的节点,n1再走,若n2找到了要删除的节点,而此时n1在要删除节点的前面,所以此时刚好可以将n1的那个节点与n2->next的节点连接在一起。

这个就是上述思路的代码实现,此时运行一下,看看能不能过掉用例。

发现这个全是要删除的节点的用例无法通过,所以还要完善代码:

这个循环就是用来解决这个用例的,当每个节点都是要删除的时,循环就不断往下走,最后返回头节点,此时已经全部删完,所以,不会显示节点的值,此时再来运行测试一下

整个代码:

也是成功通过用例。

三:链表的中间节点:

876. 链表的中间结点 - 力扣(LeetCode)

思路一:利用计数器遍历原链表计算链表节点一共有多少,然后再将所有的节点数除以2再加1即可

然后再遍历一遍,找到那个中间节点,然后返回那个中间节点的位置。

先定义一个计数器,再定义一个指针用来遍历整个链表:

这个就是整个代码了,看看能否通过:

通过了。

思路二: 快慢指针:先定义两个指针,起初两个指针都指向第一个节点的位置,两个指针同时走,慢指针走一步,快指针走两步,最后当快指针走到空时,此时返回慢指针的位置,此时就是中间节点的位置:

     若链表节点数是奇或者是偶时,循环结束的条件不一样,当链表有奇数个节点时,

fast->next==NULL,此时slow停止的位置就是中间节点的位置,当链表有偶数个节点时,fast==NULL,此时slow停止的位置就是中间节点的位置。

根据图解现在来实现代码:

可以看出快慢指针的代码更加简单。

四:环形链表的约瑟夫问题:

环形链表的约瑟夫问题_牛客题霸_牛客网 (nowcoder.com)

这就是当有五个数,数到2就被删除的图解情况。

首先先编写一个创建链表节点的函数:

节点创建完毕,接下来要创建一个环形链表将首尾节点连接起来:

当这个for循环结束ptail的位置和phead的位置,此时5和1还没有连接起来,所以循环结束还有一个将这个尾和头连接起来的操作:

这就是连接起来的代码,但是ptail不能往下移动了,正好在phead的后面即可,这才是尾。

最后将数到val的值删掉即可:

整个代码如图:

五:合并两个有序链表:

21. 合并两个有序链表 - 力扣(LeetCode)

思路:建立两个指针遍历两个链表将小的值尾插到创建的新链表中

但是这里有几种情况:

第一种就是链表一为空或链表二为空,此时就返回不为空的链表的头节点即可

上述就是准备工作,接下来写比大小来尾插的代码:

但还有一个问题,list1和list2不一定相等,有可能list1长有可能list2长,所以还要考虑谁先走到尾的情况:

整体代码如图:

总结:这几个链表题说明了要利用好链表中节点的关系,并且还介绍了快慢指针,还介绍了建立多个指针来更加简单的解决问题。

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-05-13 18:58:07       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-13 18:58:07       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-13 18:58:07       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-13 18:58:07       18 阅读

热门阅读

  1. 网络工程师----第二十六天

    2024-05-13 18:58:07       12 阅读
  2. 计算机组成与结构 计算机基本原理 软设刷题

    2024-05-13 18:58:07       14 阅读
  3. 面试被问ThreadLocal要怎么回答?

    2024-05-13 18:58:07       10 阅读
  4. 蓝桥杯备战8.快乐的跳

    2024-05-13 18:58:07       12 阅读
  5. MySQL中的事务隔离级别

    2024-05-13 18:58:07       10 阅读
  6. 每个工作室都需要的10种插件类型

    2024-05-13 18:58:07       12 阅读
  7. matlab实现K均值聚类

    2024-05-13 18:58:07       11 阅读