代码随想录day3|链表插入和删除(1)

链表理论基础

链表定义: 一种通过指针串联在一起的线性结构,每个节点均有一个数据域加一个指针域构成,最后一个结点指向NULL即空指针。
链表类型: 单链表、双链表、循环链表
python中链表节点的定义方式:

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

链表和数组的区别:
链表进行查询的时间复杂度为O(n),进行插入的时间复杂度为O(1)
数组进行查询的时间复杂度为O(1),进行插入的时间复杂度为O(n)

203.移除链表元素

# my answer
class Solution:
    def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
        h = ListNode(next=head)
        start = h
        # 如果使用star.next的话,只有当
        while start.next != None:
            if start.next.val == val:
                start.next = start.next.next
                continue
            start = start.next
        return h.next

707.设计链表

class MyLinkedList:
    # 构造函数中需要给定该列表的构造以及链表中结点的数量,将链表当成对象,后续都是直接对这个对象的引用
    def __init__(self):
        self.dummy = ListNode()
        self.cnt = 0

    def get(self, index: int) -> int:
        # 首先需要判断没有指针的情况
        if index<0 or index>=self.cnt:
            return -1
        cur = self.dummy.next
        for _ in range(index):
            cur = cur.next
        return cur.val
            
    def addAtHead(self, val: int) -> None:
        self.addAtIndex(0,val)

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

    def addAtIndex(self, index: int, val: int) -> None:
        if index > self.cnt:
            return
        pre = self.dummy
        for _ in range(index):
            pre = pre.next
        pre.next = ListNode(val, pre.next)
        self.cnt += 1 # 改变自身的长度值

    def deleteAtIndex(self, index: int) -> None:
        if index >= self.cnt:
            return
        pre = self.dummy
        for _ in range(index):
            pre = pre.next
        t = pre.next
        pre.next = t.next
        t.next = None
        self.cnt -= 1

206.反转链表

(1)双指针方法

代码随想录day3|链表插入和删除(1)_第1张图片

class Solution:
    def reverseList(self, head:Optional[ListNode]) -> Optional[ListNode]:
	# 首先进行初始化
	cur = head
	pre = None
	while cur: # 设置遍历的终止条件
		# 需要一个临时节点
		temp = cur.next
		cur.next = pre
		pre = cur
		cur = temp
	# 返回新链表的头结点
	return pre	

(2)递归的写法

递归和双指针的代码都是一一对应的,但是递归的代码更简洁,因而不容易搞清楚递归的逻辑。
关键点在于

  1. 如何理解终止条件
  2. 如何找到递归的参数
def reverse(cur, pre):
	if not cur:
		return pre
	temp = cur.next
	cur.next = pre
	return reverse(temp,cur)
reverse(head,NULL)

总结

链表章节的习题需要注意,头指针指向的是第一个节点还是第一个节点之前的节点。
熟悉链表的插入,删除等操作。

你可能感兴趣的:(链表,数据结构)