#707. 设计链表

#707. 设计链表

题目

设计链表,使得链表有以下功能:

  • 得到indexth 元素的值
  • 从头加元素
  • 从尾加元素
  • 在indexth Node前边加元素
  • 把indexth 的Node删除

解答

单链表

增、减元素:找到prev和after,再进行next的指针操作。

#Node class
class ListNode:
    def __init__(self,val):
        self.val = val
        self.next = None

#has attribute of: how many nodes inside, and the pseudo-head node
class MyLinkedList:
    def __init__(self):
        self.size = 0    #添加的节点数
        self.head = ListNode(0) #虚拟头部节点

    def get(self, index: int) -> int:
        #invalid cases of index
        if index < 0 or index >= self.size:
            return -1
        #index + 1, 因为head是幽灵head
        curr = self.head
        for i in range(index + 1):
            curr = curr.next
        return curr.val


    def addAtHead(self, val: int) -> None:
        self.addAtIndex(0, val)

    def addAtTail(self, val: int) -> None:
        self.addAtIndex(self.size, val)

    def addAtIndex(self, index: int, val: int) -> None:
        #如果index > size 则不考虑
        if index > self.size:
            return
        #如果index < 0, 那么仍然valid,cast index为0
        if index < 0:
            index = 0
        
        #add size don't forget
        self.size += 1
        #find predecessor
        pred = self.head
        for i in range(index):
            pred = pred.next
            
        after = pred.next
        to_add = ListNode(val)
        
        pred.next = to_add
        to_add.next = after
            
    def deleteAtIndex(self, index: int) -> None:
        #如果index小于self.size, 证明valid,则再进行运算
        if index < self.size:
            self.size -= 1
            pred = self.head
            
            for i in range(index):
                pred = pred.next
            after = pred.next.next
            pred.next = after

###双链表

#Node class
class ListNode:
    def __init__(self,val):
        self.val = val
        self.next = None
        self.prev = None

#has attribute of: how many nodes inside, and the pseudo-head node
class MyLinkedList:
    def __init__(self):
        self.size = 0    #添加的节点数
        self.head = ListNode(0) #虚拟头部节点
        self.tail = ListNode(0) #虚拟尾部节点
        self.head.next = self.tail
        self.tail.prev = self.head

    def get(self, index: int) -> int:
        #invalid cases of index
        if index < 0 or index >= self.size:
            return -1
        #如果index > 一半,则往后找
        if index >= self.size // 2:
            curr = self.tail
            for i in range(self.size - index):
                curr = curr.prev
        #如果index < 一半,则往前找
        else:
            curr = self.head
            for i in range(index + 1):
                curr = curr.next
        return curr.val

    def addAtHead(self, val: int) -> None:
        self.addAtIndex(0, val)

    def addAtTail(self, val: int) -> None:
        self.addAtIndex(self.size, val)

    def addAtIndex(self, index: int, val: int) -> None:
        if index > self.size:
            return
        
        if index < 0:
            index = 0
        #如果index 小于一半,则从前往后找,输出prev,succ
        if index < self.size // 2:
            pred = self.head
            for i in range(index):
                pred = pred.next
            succ = pred.next
        #如果index 大于一半,则从后往前找,输出prev,succ
        else:
            succ = self.tail
            for i in range(self.size - index):
                succ = succ.prev
            pred = succ.prev
            
        #处理链表的指针关系
        #add size don't forget
        self.size += 1
        to_add = ListNode(val)
        pred.next = to_add
        to_add.next = succ
        succ.prev = to_add
        to_add.prev = pred
            
    def deleteAtIndex(self, index: int) -> None:
        if index >= self.size or index < 0:
            return
        #如果index 小于一半,则从前往后找,输出prev,succ
        if index < self.size // 2:
            pred = self.head
            for i in range(index):
                pred = pred.next
            succ = pred.next.next
        #如果index 大于一半,则从后往前找,输出prev,succ
        else:
            succ = self.tail
            for i in range(self.size - 1 - index):
                succ = succ.prev
            pred = succ.prev.prev
            
        self.size -= 1
        pred.next = succ
        succ.prev = pred

收获

  1. MyLinkedList有两个fields: size (Node的数量),以及 head (幽灵节点,指向第一个元素,类同dummy)
  2. 双链表记得创建head和tail
  3. 画图大法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值