算法训练营 Day 03| 链表

58 阅读2分钟

链表

  • 线性结构 数据域+指针域
    • 区别于数组,链表中的节点在内存中不是连续分布的 ,而是散乱分布在内存中的某地址上 image.png
  • 类型
    • 单链表
    • 双链表
    • 循环链表
  • 定义
class linkedList():
    def __init__(self, val, next=None):
        self.val = val
        self.next = next

203. 移除链表元素

通过构造前序节点来实现跳过(删除)某节点

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
        # initial the dummy node -> head
        if not head:
            return 
        dummy = ListNode()
        dummy.next = head
        pre = dummy
        
        while pre and pre.next:
            if pre.next.val == val:
                pre.next = pre.next.next
            else:
                # in case the next == val
                pre = pre.next
        return dummy.next

或用当前节点

def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
    # initial the dummy node -> head
    if not head:
        return 
    dummy = ListNode()
    dummy.next = head
    pre = dummy
    cur = head
    
    while cur:
        if cur.val == val:
            pre.next = cur.next
        else:
            # in case the next == val
            pre = pre.next
        cur = cur.next
    return dummy.next

707. 设计链表

采用设置虚拟头结点的方式

  • 获取链表第index个节点的数值
  • 在链表的最前面插入一个节点
  • 在链表的最后面插入一个节点
  • 在链表第index个节点前面插入一个节点
  • 删除链表的第index个节点

需要注意各个功能边界条件

单链表

# Single LinkedList
class Node:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class MyLinkedList:
    def __init__(self):
        self.head = Node()

    def get(self, index: int) -> int:
        cur = self.head.next
        while index:
            if not cur:
                return -1
            cur = cur.next
            index -= 1
        return cur.val if cur else -1

    def addAtHead(self, val: int) -> None:
        pre = Node(val)
        # update the second element
        pre.next = self.head.next
        self.head.next = pre

    def addAtTail(self, val: int) -> None:
        cur = self.head
        while cur.next:
            cur = cur.next
        cur.next = Node(val)

    def addAtIndex(self, index: int, val: int) -> None:
        cur = self.head
        while index:
            cur = cur.next
            index -= 1
        if not cur:
            return
        temp = cur.next
        newone = Node(val)
        cur.next = newone
        newone.next = temp


    def deleteAtIndex(self, index: int) -> None:
        cur = self.head
        while index and cur:
            cur = cur.next
            index -= 1
        if cur and cur.next:
            cur.next = cur.next.next



# Your MyLinkedList object will be instantiated and called as such:
# obj = MyLinkedList()
# param_1 = obj.get(index)
# obj.addAtHead(val)
# obj.addAtTail(val)
# obj.addAtIndex(index,val)
# obj.deleteAtIndex(index)

也可用双链表结构实现 随想录707

206. 反转链表

需要注意初始化pre=None,否则反转后会多出pre节点

def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:

    pre = None
    cur = head

    while cur:
        temp = cur.next
        cur.next = pre
        pre = cur
        cur = temp

    return pre