LeetCode题解—求链表的中间结点

简介: 没错,今天又是算法,马上放假啦,心已经飞走了。

前言


没错,今天又是算法,马上放假啦,心已经飞走了。


明天是过年前的最后一篇:面试题思考与解答1月刊。


今天继续说说链表算法题:求链表的中间结点。



题目:求链表的中间结点


给定一个头结点为 head 的非空单链表,返回链表的中间结点。


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


示例 1:输入:[1,2,3,4,5] 输出:此列表中的结点 3


(序列化形式:[3,4,5]) 返回的结点值为 3 。


(测评系统对该结点序列化表述是 [3,4,5])。注意,我们返回了一个 ListNode 类型的对象 ans,这样:ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.


示例 2:输入:[1,2,3,4,5,6] 输出:此列表中的结点 4


(序列化形式:[4,5,6])


由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。


解法一


题目意思还是比较简单的,就是找到中间结点。


首先想到的就是先算出来链表总长度,然后再遍历到中间结点就可以了:


public ListNode middleNode(ListNode head) {
        int n = 0;
        ListNode cur = head;
        while (cur != null) {
            n++;
            cur = cur.next;
        }
        int k = 0;
        cur = head;
        while (k < n / 2) {
            k++;
            cur = cur.next;
        }
        return cur;
    }


时间复杂度


一共遍历了1次加半次。去除常量,时间复杂度为O(n)


空间复杂度


只用到单独的一个链表结点,空间复杂度为O(1)


解法二


还记得上一篇我们说到的找到结尾第n个结点算法题吗?其中用到了一个叫做快慢指针的解法。


在这里依然可以用到。可能你就有疑惑了,上一次是知道两个指针之间相隔n个结点,这一次怎么用呢?


如果我们将慢指针每次移动一格,快指针每次移动两格,那么快指针是不是每次都是慢指针的两倍步数呢?


这样当快指针移到尾部的时候,慢指针就刚好在中间结点了。


public ListNode middleNode(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }


这里因为每次fast都要移动两步,所以需要判断当前结点和下一个结点是否都为空。


slow 1  2  3  4  5  6  
fast 1  3  5  7  9  11


上面的例子就是快慢指针会走到的节点数:


  • 如果链表为奇数,比如[1,2,3,4,5],那么刚好快慢结点就会走到3和5
  • 如果链表为奇数,比如[1,2,3,4,5,6],那么刚好快慢结点就会走到4和null


时间复杂度


用到了遍历,所以时间复杂度还是O(n)


空间复杂度


空间复杂度为O(1)


其他解法


如果该题是数组的话,是不是一句代码就能解出来呢?Array[n/2]。所以我们完全可以将链表转化成数组,然后一句代码就可以输出中间结点数了,你可以动手试试哦。

这种解法的时间复杂度和空间复杂度又是多少呢?


参考


https://leetcode-cn.com/problems/middle-of-the-linked-list/

目录
相关文章
|
2月前
【力扣】-- 移除链表元素
【力扣】-- 移除链表元素
37 1
|
2月前
Leetcode第21题(合并两个有序链表)
这篇文章介绍了如何使用非递归和递归方法解决LeetCode第21题,即合并两个有序链表的问题。
51 0
Leetcode第21题(合并两个有序链表)
|
2月前
|
算法
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
71 1
|
1月前
|
存储 算法 搜索推荐
链表的中间结点
【10月更文挑战第24天】链表的中间结点是链表操作中的一个重要概念,通过快慢指针法等方法可以高效地找到它。中间结点在数据分割、平衡检测、算法应用等方面都有着重要的意义。在实际编程中,理解和掌握寻找中间结点的方法对于解决链表相关问题具有重要价值。
20 1
|
2月前
LeetCode第二十四题(两两交换链表中的节点)
这篇文章介绍了LeetCode第24题的解法,即如何通过使用三个指针(preNode, curNode, curNextNode)来两两交换链表中的节点,并提供了详细的代码实现。
22 0
LeetCode第二十四题(两两交换链表中的节点)
|
2月前
Leetcode第十九题(删除链表的倒数第N个节点)
LeetCode第19题要求删除链表的倒数第N个节点,可以通过快慢指针法在一次遍历中实现。
44 0
Leetcode第十九题(删除链表的倒数第N个节点)
|
2月前
|
索引
力扣(LeetCode)数据结构练习题(3)------链表
力扣(LeetCode)数据结构练习题(3)------链表
91 0
|
2月前
【LeetCode 10】142. 环形链表 II
【LeetCode 10】142. 环形链表 II
22 0
|
2月前
【LeetCode 09】19 删除链表的倒数第 N 个结点
【LeetCode 09】19 删除链表的倒数第 N 个结点
17 0
|
2月前
【LeetCode 08】206 反转链表
【LeetCode 08】206 反转链表
13 0