时间:2020-6-7
题目地址:https://leetcode-cn.com/problems/middle-of-the-linked-list/
题目难度:Easy
题目描述:
给定一个带有头结点 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 之间。
思路1:使用快慢指针
代码段1:通过
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
if(head == None): return None
odd, even = head, head
while(even.next != None):
if(even.next.next == None):
odd = odd.next
break
else:
odd = odd.next
even = even.next.next
return odd
总结:
- 使用操作多画了几遍,快慢指针的思路就来了,而且是一遍过,开心极了
- 我发现我对于结束的条件总是想的有问题,可能是因为我这个人比较懒,不爱多动脑子吧,这个得改,下边是优化版本的
- 现在做题不是一上来就写代码了,而是想出基本解法后寻求最佳解法。比如这道题,第一个想到是的 第一次遍历求得链表的长度,第二遍历到 N/2 的即可,还有一种思路是把链表元素放到列表里,这样就可以直接获取 N/2。不过显然是快慢指针比较好
- 这里还有个点期望 【如果有两个中间结点,则返回第二个中间结点】这里通过自己左右手的两根手指同步移动可以得到:快指针可以前进的条件是:当前快指针和当前快指针的下一个节点都非空;【如果有两个中间结点,则返回第一个中间结点】可以得到:快指针可以前进的条件是:当前快指针的下一个节点和当前快指针的下下一个节点都非空
- 大神总结的解决链表问题的常见技巧:递归函数-避免复杂的改变指针变量指向操作,使得求解问题变得简单;虚拟头节点-哨兵;快慢指针-同步指针;为链表编写测试函数
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
odd, even = head, head
while(even != None and even.next != None):
odd = odd.next
even = even.next.next
return odd