美文网首页
Python数据结构-链表Ⅱ(Linked List)

Python数据结构-链表Ⅱ(Linked List)

作者: ShowMeCoding | 来源:发表于2022-01-12 20:29 被阅读0次
328. 奇偶链表

给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。
请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。

示例 1:
输入: 1->2->3->4->5->NULL
输出: 1->3->5->2->4->NULL

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def oddEvenList(self, head: ListNode) -> ListNode:
        # 边界条件判定
        if not head or not head.next or not head.next.next:
            return head
        # 奇数头节点
        jishu = head
        isjishu = True          # 标记奇数位
        # 先保存偶数头节点
        oushu0 = head.next
        # 偶数头节点
        oushu = head.next
        cur = head.next.next

        while cur:
            # 先把相邻的奇数位、偶数位链表挑选出来
            if isjishu:
                jishu.next = cur
                jishu = cur
            else:
                oushu.next = cur
                oushu = cur
                # 用于判断奇数位是否结束
            isjishu = not isjishu
            cur = cur.next
        # 最后将奇数位链表的最后一个节点与偶数位链表的头节点相连
        jishu.next = oushu0
        # 偶数位链表最后一位与空相连
        oushu.next = None
        return head
234. 回文链表

输入:head = [1,2,2,1]
输出:true

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        # 辅助数据按顺序存储链表元素
        items = []
        cur = head
        while cur:
            items.append(cur.val)
            cur = cur.next
        return items == items[::-1]
61. 旋转链表

输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]
解释:[1,2,3,4,5]==>[5,1,2,3,4]==>[4,5,1,2,3]

class Solution:
    def rotateRight(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
        if not head or not head.next or k == 0:
            return head
        # 把尾部的k个节点放在最前面
        # 链表长度
        count = 1
        cur  = head
        while cur.next:
            count += 1
            cur = cur.next
        # 反向链接
        cur.next = head
        # 旋转次数,前t个链表移动到后面
        t = count - k % count
        while t > 0:
            cur = cur.next
            t -= 1
        # 新的头节点
        newhead = cur.next
        # 断开节点
        cur.next = None
        return newhead
19. 删除链表的倒数第 N 个结点

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        # 双指针
        dummy = ListNode(0,head)     # 哑结点
        slow = dummy
        fast = head
        for i in range(n):           # slow和fast中间相隔两个 n 个结点
            fast = fast.next
        
        while fast is not None:      # 当fast到达末尾,slow所指的下一个节点将被删除
            slow = slow.next
            fast = fast.next
        
        # 删除节点元素
        slow.next = slow.next.next   
        return dummy.next
876. 链表的中间结点

给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

# 使用快慢指针
class Solution:
    def middleNode(self, head: ListNode) -> ListNode:
        slow = head
        fast = head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
        return slow


# 1 使用辅助数组
class Solution:
    def middleNode(self, head: ListNode) -> ListNode:
        l = [head]
        while l[-1].next:
            l.append(l[-1].next)
        return l[len(l)//2]

# 2 先获取链表的长度n,之后遍历到 n//2为止
class Solution:
    def middleNode(self, head: ListNode) -> ListNode:
        n = 0
        tmpnode = head
        while tmpnode:
            tmpnode = tmpnode.next
            n += 1
        i = 0
        cur = head
        while i < n//2:
            cur = cur.next
            i += 1
        return cur
141. 环形链表

给你一个链表的头节点 head ,判断链表中是否有环。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

# 方法1:使用一个哈希表
# 思路:使用一个哈希表来存储所有已经访问过的节点,如果该节点存在于哈希表中,则说明该链表是环形链表

class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        seen = set()
        while head:
            if head in seen:
                return True
            seen.add(head)
            head = head.next
        return False

# # 方法2:快慢指针
# # 思路:快指针每次移动一步,慢指针每次移动两步,如果快指针追上慢指针,则为环形链表
class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        # 边界条件
        if head == None or head.next == None:
            return False

        # 快慢指针
        slow = head
        fast = head.next
        
        while slow != fast:
            if fast == None or fast.next == None:
                return False
            slow = slow.next         # 每次走一步
            fast = fast.next.next    # 每次走两步
        return True
21. 合并两个有序链表

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        prevHead = ListNode(-1)
        prev = prevHead
        while l1 and l2:
            if l1.val <= l2.val:
                prev.next = l1
                l1 = l1.next
            else:
                prev.next = l2
                l2 = l2.next
            prev = prev.next
        if l1 is not None:
            prev.next = l1
        else:
            prev.next = l2
        return prevHead.next
142. 环形链表 II

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        slow = head
        fast = head
        while True:
            if fast == None or fast.next == None:
                return None
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                break
        ans = head
        while ans != slow:
            ans = ans.next
            slow = slow.next
        return ans
160. 相交链表

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        # 思路:采用双指针,分别指向两链表的头节点
        # 指针A先遍历完链表headA,再开始遍历headB
        # 指针B先遍历完链表headB,再开始遍历headA
        A, B = headA, headB
        while A != B:
            A = A.next if A else headB
            B = B.next if B else headA
        return A

相关文章

网友评论

      本文标题:Python数据结构-链表Ⅱ(Linked List)

      本文链接:https://www.haomeiwen.com/subject/yhaicrtx.html