代码随想录算法训练营第三天|203.移除链表元素, 707.设计链表, 206.反转链表

重要知识点: 

1. 链表的定义: 链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)

2. 链表的形式: 单链表, 双链, 循环链。 自己之前接触单链表和循环链表比较多点。

3. 链表数据的储存方式: 非连续的, 通过节点的指针串起来的。 和数组有本质的区别

4. 链表和数组的对比:链表增加/删除节点时间复杂度 O(1),数组 O(n), 因为数组要向前覆盖后面的所有数据, 链表只需要改变指针的指向。链表查询的时间复杂度 O(n), 数组O(1)。 因为链表储存空间不连续, 需要从 head 开始往后查找。 链表和数组有各自的优劣势。

203.移除链表元素:

思路:循环链表的所有节点,如果看到一个节点的值等于特定值, 需要讲该节点前一个节点的指针, 指向该节点后一个指针。 但是因为单链表往前退一个节点很麻烦, 所以每次检查当前节点的下一个节点的值是不是等于特定值。 如果是的话, 就让当前节点的指针指向下一个节点的下一个节点。 这样需要对head 的值比较小心, 如果当前节点从head 开始就会忽略掉head值等于特定值的情况。 所以我的做法是给链表的head 前面在增加一个node(node的值无所谓)。循环从新增的node 开始就行了。

难点: 开头的节点

# 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]:
        start_node = ListNode(0)
        start_node.next = head
        current_node = start_node
        while current_node:
            next_node = current_node.next
            if next_node and next_node.val == val:
                current_node.next = next_node.next
            else:
                current_node = current_node.next
        return start_node.next

707.设计链表

思路: 要求定义 myLinkedList 类, 然后按照要求写 member function 就可以了, 都是些基本的增加,删除,查找元素。

难点: 有些特殊情况需要考虑,例如 head 是 None 的时候如何增加元素。 这里我是做了特殊处理, 但是应该也可以考虑上一题的处理开头的思路把特殊情况变为一般情况。

class MyLinkedList:

    def __init__(self, head: ListNode = None):
        self.head = head 

    def get(self, index: int) -> int:
        tmp_node = self.head
        i = 0
        while tmp_node:
            if i == index:
                return tmp_node.val
            i += 1
            tmp_node = tmp_node.next
        return -1

    def addAtHead(self, val: int) -> None:
        new_node = ListNode(val)
        new_node.next = self.head
        self.head = new_node
        return

    def addAtTail(self, val: int) -> None:
        if not self.head: 
            self.addAtHead(val)
            return 
        new_node = ListNode(val)
        tmp_node = self.head
        while tmp_node:
            if not tmp_node.next:
                tmp_node.next = new_node
                break
            tmp_node = tmp_node.next
        return

    def addAtIndex(self, index: int, val: int) -> None:
        new_node = ListNode(val)
        if index==0: self.addAtHead(val)
        i = 1
        tmp_node = self.head
        while tmp_node and i<=index:
            if i == index:
                new_node.next = tmp_node.next
                tmp_node.next = new_node
            i += 1
            tmp_node = tmp_node.next
        return

    def deleteAtIndex(self, index: int) -> None:
        if index == 0: self.head = self.head.next
        tmp_node = self.head
        i = 1
        while tmp_node and tmp_node.next and i <= index:
            if i == index:
                tmp_node.next = tmp_node.next.next
            tmp_node = tmp_node.next
            i += 1
        return 

206.反转链表:

思路: 单链表不容易向前循环。 因此处理的时候先定义了一个 prev_node = None (记录反正链表的head),  然后从 head 开始循环链表, 先用 tmp_node 记录当前节点, 然后 head 往后移动, 然后 tmp_node 节点的指针指向 prev_node, 最后 prev_node 更新到 tmp_node. 这里head 要先往后跑一个在改tmp_node 的指针。 要不然head 就跳出input 链表了。 

难点: 先跑head 再改指针。 

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        prev_node = None
        while head:
            tmp_node = head
            head = head.next
            tmp_node.next = prev_node
            prev_node = current_node
        return prev_node
        

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值