LeetCode-链表的中间结点

题目描述:

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

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

示例:

输入:[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.

输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。

解题思路:

三种解题方式(参考官方题解):

(1)利用数组。将各个结点遍历并加到列表中,遍历完成得到一个新列表后,计算列表长度,整除取其平均值(//2)作为列表下标,根据该下标获取中间结点。时间复杂度O(n),空间复杂度O(n)。

(2)利用单指针。由于方法一利用了一个新数组,造成使用内存空间增加,对其进行改进。首先遍历一遍链表,获取该链表的长度。之后再次遍历该链表,当遍历到该链表长度的一半时,返回该结点。此时的节点为链表的中间结点。

(3)利用快慢指针。其原理是利用两个指针-> slow、fast,slow每次走一个结点(n),fast每次走两个结点(2n),当fast走到链表末尾时,刚好slow指向的就是中间结点。但需要考虑fast走到最后是空的情况。

代码:

class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None


class Solution:
def middleNode(self, head: ListNode) -> ListNode:
"""第一种方法:数组"""
# l = [head]
# while l[-1].next:
# l.append(l[-1].next)
# return l[len(l) // 2]
"""第二种方法: 单指针"""
# num, cur = 0, head
# while cur:
# num += 1
# cur = cur.next
# i, cur = 0, head
# while cur:
# if i == num // 2:
# return cur
# else:
# i += 1
# cur = cur.next
"""第三种方法: 快慢指针"""
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow

猜你喜欢

转载自www.cnblogs.com/RiverMap/p/12555059.html