想到使用快慢指针法,但是只需要慢指针即可,具体解法见图示。
快慢指针法教学地址为:https://blog.csdn.net/qq_22795223/article/details/104247626
接下来直接上代码:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
prev = None
slow = head
# fast = head
Next = slow
if (head is None) or (head.next is None):
return head
while(slow != None):
# fast = fast.next.next
Next = slow.next
slow.next = prev
prev = slow
slow = Next
return prev
一开始想着用一个指针来做,但是发现不行,那么还是可以使用快慢指针法去进行解决,具体分析见图。
再直接上代码:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if head == None:
return False
slow = head
fast = head
while((fast != None) and (fast.next != None)):
# 奇数和偶数两种情况都不能放过
slow = slow.next
fast = fast.next.next
if (slow == fast):
return True
return False
这题一开始使用快慢指针法的变形即slow和fast均各走一步,但是发现prev指向的是None,最后输出的结果反而是全部为逆序,弄巧成拙了,后来才反应过来,如果prev指向的不是None,指向的是哨兵,那么哨兵则可以直接.next添加下一个结点,这是极其方便的,而且哨兵可以固定住单链表头,最后直接输出哨兵.next,即输出了全部的单链表。
具体见图解:
接下来直接上代码,这题还可以用递归的方法去做,这里递归还没有非常完整的学习体系,所以暂且不提:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
prehead = ListNode(-1) # 哨兵
prev = prehead
# cur1 = l1
# cur2 = l2 不太需要这两个游标
while (l1 and l2):
if l1.val <= l2.val:
prev.next = l1
prev = l1
l1 = l1.next
else:
prev.next = l2
prev = l2
l2 = l2.next
if l2 != None:
prev.next = l2
if l1 != None:
prev.next = l1
return prehead.next
有两种方法,第一种方法是两次遍历,第二种方法是快慢指针,我们逐一介绍。
两次遍历
第一次遍历确定长度,然后通过长度L与n的差值,来确定要删除结点的前继结点位置。
第二次遍历到前继结点位置,进行删除目标结点即可。
直接上代码,太简单了:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
if head.next == None and n == 1:
return None
prehead = ListNode(-1)
prehead.next = head
pre = prehead
L = 1
while (pre.next != None):
pre = pre.next
L += 1
d = L - n
count = 1
pre = prehead
while (count != d):
pre = pre.next
count += 1
pre.next = pre.next.next
return prehead.next
快慢指针
首先slow指针不动,fast指针每次动一次,同时计算slow和fast之间的间隔between;当between-1与n相等时,slow和fast才同时每次移动一次;当fast移动到指向None时,跳出移动的循环;此时的slow指向前继结点,直接删去目标结点即可。
动图网址为:https://pic.leetcode-cn.com/cc43daa8cbb755373ce4c5cd10c44066dc770a34a6d2913a52f8047cbf5e6e56-file_1559548337458
看一下伪代码画图过程:
接下来上代码:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
if head.next == None and n == 1:
return None
prehead = ListNode(-1)
prehead.next = head
slow = prehead
fast = prehead
between = 0
while (between - 1 != n):
fast = fast.next
between += 1
while (fast != None):
slow = slow.next
fast = fast.next
slow.next = slow.next.next
return prehead.next
快慢指针即可解决
最后直接上代码:
# 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
"""
# prev = head 没必要了
slow = head
fast = head
# count = 0 没必要了
while fast != None and fast.next != None:
# count += 1 没必要了
slow = slow.next
fast = fast.next.next
# while (count != 0):
# prev = prev.next
# count -= 1
# return prev
return slow # 直接返回slow即可