leetcode 876. Middle of the Linked List 链表的中间结点 快慢指针
leetcode 2020年3月 每日一题打卡
题目:
给定一个带有头结点 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,我们返回第二个结点。
提示:
给定链表的结点数介于 1 和 100 之间。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/middle-of-the-linked-list
3种方法:
- 数组:遍历链表,将node依次放入数组 A 中,最后取数组中间下标内存储的node。时间复杂度O(N), N 为链表中的结点数目。空间复杂度O(N),即数组 A 用去的空间。
- 单指针法:对链表进行两次遍历。第一次遍历统计链表中的节点数目 N;第二次遍历到第 N/2 个node时返回。时间复杂度O(N),空间复杂度O(1)。
- 快慢指针法:用两个指针 slow 与 fast 一起遍历链表。slow 一次走一步,fast 一次走两步。那么当 fast 到达链表的末尾时,slow 必然位于中间。时间复杂度O(N),空间复杂度O(1)。
细节:
- / 表示 浮点数除法,返回浮点结果;// 表示整数除法,向下取整。
- 链表结构:node类(本身也是一个指针)中:data为数据,next为下一个节点的地址(指针)。 head为头结点。
- c++中有指针,python中没有真正意义上的指针,python对指针做了良好封装,一切都是“对象”,一切对象都有一个“变量”指向它。这个“变量”就是“指针”。在python中每个变量都是指针。
代码1 数组法:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def middleNode(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
A = [head]
while A[-1].next:
A.append(A[-1].next)
return A[len(A) // 2]
代码2 单指针法:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def middleNode(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
n, cur = 0, head
while cur:
n += 1
cur = cur.next
k, cur = 0, head
while k < n // 2:
k += 1
cur = cur.next
return cur
代码3 快慢指针法:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def middleNode(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# 快慢指针
fast = head
slow = head
while fast and fast.next:
slow=slow.next
fast=fast.next.next
return slow