奇偶链表
问题描述
给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。
请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。
例子
image.png
思路
因为要原地完成,所以修改head指针next指向的位置。
1 存储奇数节点的头节点和偶数节点的头节点
2 将下一个节点链接到对应的头节点
3 将奇数和偶数节点相连
class Solution:
def oddEvenList(self, head: ListNode) -> ListNode:
if not head:
return head
ji=head#奇数
ou=ou_head=head.next#偶数
while ji.next and ou.next:
ji.next=ji.next.next
ou.next=ou.next.next
ji,ou=ji.next,ou.next
ji.next=ou_head #相连
return head
环路检测
问题描述
给定一个有环链表,实现一个算法返回环路的开头节点。
有环链表的定义:在链表中某个节点的next元素指向在它前面出现过的节点,则表明该链表存在环路。
例子
image.png
思路
1 使用字典,遍历链表,每次将节点存储到字典中,如果节点重复,返回该节点,否则返回空,
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
hashDict = {}#字典
while head:
if head not in hashDict:
hashDict[head] = 1
else:
return head #返回该节点
head = head.next
return None
2 使用快慢指针,让慢指针每次移动一格,快指针每次移动2格,如果存在环,则两个指针必定会相遇。
那如何找到循环的起始位置呢,让快指针再相遇的位置,慢指针再head起点,两个指针以1 的速度移动,相遇的位置就是循环的起始位置(我也不是很懂)。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
slow, fast = head, head
while fast and fast.next: #开始走位
slow = slow.next
fast = fast.next.next
if slow == fast: # 相遇
break
# 若无相会处,则无环路
if not fast or not fast.next:
return None
# 若两者以相同的速度移动,则必然在环路起始处相遇
slow = head
while slow != fast:
slow = slow.next
fast = fast.next
return slow
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/odd-even-linked-list