奇偶链表和环路检测

奇偶链表

问题描述
给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。

请尝试使用原地算法完成。你的算法的空间复杂度应为 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

你可能感兴趣的:(奇偶链表和环路检测)