1. 碎碎念

遥想后端君当年,曾经也是学校ACM队的一员,但参加过级别最高的比赛,同时也是ACM方面获得的最大成就,不过是天梯赛三等奖(当时天梯赛在浙江还只是省B级别的,现在已经算国赛了),犹记得当时的分数是120多分,满分是200还是160来着我忘记了,反正成绩比平均分高了大概20分。

现在回想起来,总体还是感觉自己是个打酱油的,普通的算法题做做还行,难的比如动态规划、贪心、搜索、图论啥的,就不太会了。

而如今的大厂面试,几乎都会有笔试轮,让现场手写算法题,要是笔试都没过,那与面试官手撕HashMap、JVM、各种框架原理都没有机会上演。由此可见算法的重要性,所以后端君决定开始重学数据结构与算法,每天都会抽出一个小时时间来练习。

2. 题目

今天练习的主题是快慢指针法,对应LeetCode上的题目是第876题——链表的中间结点。

题目的要求是给定一个链表的头结点head,返回这个链表的中间节点。

给定的链表数据结构为

例如,当链表为[1,2,3,4,5]时,返回的是值为3的节点;当链表为[1,2,3,4,5,6]时,返回的是值为4的节点。

当然我们可以先遍历一遍链表,得到链表的长度,然后计算出中间节点的索引值,最终通过迭代去获得中间节点。

这样虽然最终也能得到结果,但怎么说呢,不优雅。

而下面要讲的快慢指针法,只需要通过一次遍历就能够得到答案,相对来说就比较优雅且高效。

3. 快慢指针法

快慢指针法在寻找链表中间节点这道题上的的思路是这样:通过两个指针遍历链表,快指针每次走2步,慢指针每次走1步,那么当快指针走到链表尾部的时候,慢指针恰好走到链表的中间节点,然后遍历结束,返回慢指针即为链表中间节点。

先来看第一个示例,当链表为[1,2,3,4,5]时,灵魂画手上线,这时链表是这样子的(我们用白色的箭头来表示慢指针,黑色的箭头来表示快指针):

链表初始状态

当两个指针经过第1次移动后,快指针走到3的位置,慢指针走到2的位置,这时链表是这样子的:

第1次移动后的链表

当两个指针经过第2次移动后,快指针走到5的位置,慢指针走到3的位置,这时链表是这样子的:

第2次移动后的链表

当要进行第3次移动到,发现快指针已经走到了链表尾部节点,即fast.next == null,于是退出遍历,直接返回慢指针,也就是值为3的节点。

这时当链表节点数为奇数的时候的题解步骤,若节点数为偶数,就有一些不同的,比如链表为[1,2,3,4,5,6]时,在第3次移动后快指针走到了NULL指针的位置,慢指针走到了4的位置,如下图所示:

第3次移动后的链表

这时候的判断就不是快指针走到链表尾部节点了,而是快指针本身就是一个空节点。

所以综合链表长度为奇数和偶数的两种情况,遍历链表结束的条件应该是:快指针为空或快指针走到链表尾部节点(即快指针的下一个阶段为空)。

所以,这道题的快慢指针解法应该是下面这样子。

4. 拓展

寻找链表中间节点只是快慢指针法的一种应用,快慢指针法还能够用在很多算法题中,比如寻找链表中倒数第k个节点、判断一个链表是不是环形链表等等。

这两题的分别是剑指Offer第22题和Leetcode第141题,有兴趣的同学可以去做做。

5. 小结

本文通过LeetCode上的一道寻找链表中间节点的题目来描述了一下快慢指针法,这是一个普通却又并不简单的算法。后端君认为,在应用快慢指针法时,我们需要注意的是遍历结束条件以及快慢指针分别如何移动,在确定了这两个步骤之后才能够真正运用这个算法来解决问题。

今天的快慢指针法,你学会了吗?

版权声明:本文为Planeswalker23所创,转载请带上原文链接,感谢。

本文使用 mdnice 排版

java 查找链表中间元素,如何找到链表的中间节点?相关推荐

  1. java查看链表指定元素_Java 实例 – 链表元素查找

    Java 实例 - 链表元素查找 以下实例演示了使用 linkedlistname.indexof(element) 和 linkedlistname.Lastindexof(elementname) ...

  2. Java查找数组重复元素,并打印重复元素、重复次数、重复元素位置

    面试题查找重复元素并打印重复次数和重复位置,一顿懵逼,回来死磕写下来,打印指定重复次数和最大次数,其他在此基础上可以再更新 package sort; import org.testng.annota ...

  3. Java数据结构与算法———(10)单链表应用实例,找到单链表中倒数第K个节点

    找到单链表中的倒数第K个节点,并打印输出节点.两段代码,思路都是相似的. 一.代码1 public class SingleLinkedListDemo {public static void mai ...

  4. java有链表吗_Java数据结构之链表(Linked List)

    1.链表(Linked List)介绍 链表是有序的列表,但是它在内存存储结构如下: 2.特点: 链表是以节点的方式来存储,是链式存储 每个节点包含 data 域, next 域:指向下一个节点. 链 ...

  5. 链表(Linked List)之单链表

    原文地址:传送门 链表(Linked List)介绍 链表是有序的列表,但是它在内存中是存储如下 小结: 链表是以节点的方式来存储,是链式存储 每个节点包含 data 域, next 域:指向下一个节 ...

  6. 如何理解C语言链表,如何理解c语言链表

    C语言链表就是一种数据结构,可以在上面动态的进行传输分配还可以定义节点数据类别或者实现对节点的增删改查等 链表是一种常见的基础数据结构,结构体指针在这里得到了充分的借助.链表可以动态的进行传输分配,也 ...

  7. java 查找链表中间元素_如何在Java中一次性查找Java中链表的中间元素

    如何在一次传递中找到LinkedList的中间元素?这是一个 Java 和非Java程序员面试时经常被问到的编程问题.这个问题类似于检查回文或计算阶乘,有时也会要求编写代码.为了回答这个问题,候选人必 ...

  8. java查找链表中间元素_如何通过Java单次查找链表的中间元素

    java查找链表中间元素 您如何一次找到LinkedList的中间元素是一个编程问题,在电话采访中经常问Java和非Java程序员. 这个问题类似于检查回文或 计算阶乘 ,有时Interviewer还 ...

  9. java 查找链表中间元素_java查找链表中间元素_如何通过Java单次查找链表的中间元素...

    java查找链表中间元素 您如何一次找到LinkedList的中间元素是一个编程问题,在电话采访中经常问Java和非Java程序员. 这个问题类似于检查回文或 计算阶乘 ,有时Interviewer还 ...

最新文章

  1. C++ 百炼成钢20
  2. masm5安装教程_汇编语言程序环境搭建masm+debug64位 win10/7
  3. C++服务器设计(七):聊天系统服务端实现
  4. 使用TVP批量插入数据
  5. 大数据给教育带来怎样的可能?
  6. 【Recat 应用】之 React 脚手架
  7. 程序导致IIS服务器应用程序池停止
  8. 【pyhon】nvshens图片批量下载爬虫1.01
  9. 如何强制卸载edge_如何卸载微软Windows10自带的Edge浏览器?试试这个方法
  10. 漫话:如何给女朋友解释什么是撞库、脱库和洗库?
  11. Visual Basic6.0下载及安装
  12. php paypal ipn,PHP 开发详解:PayPal Instant Payment Notification (IPN)
  13. 手机浏览器跳微信小程序
  14. SEO: 使用 rel=canonical 为类似网页或重复网页指定权威网页
  15. Android之光线传感器
  16. php实训目的及意义,ps实训目的
  17. 讲的真详细!花三分钟看完这篇文章你就懂了
  18. Linux下php重启的问题
  19. source insight如何设置背景
  20. 【FFmpeg在Intel GPU上的硬件编解码实现】

热门文章

  1. 基于iOS用CoreImage实现人脸识别
  2. Log4j2 - java.lang.NoSuchMethodError: com.lmax.disruptor.dsl.Disruptor
  3. Java - “JUC”原子类
  4. Android4.0源码目录结构详解
  5. 调试中除了在URL上加时间戳外,如何避免js、css被返回304状态?
  6. vb.net机房收费系统之组合查询
  7. android自定义悬浮控件
  8. php 换行输出_Fracker:PHP函数调用追踪与分析工具
  9. 浏览器获取CA认证流程
  10. Emacs收发email