链表理论基础
链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。
单链表:
上文所说即单链表
双链表:
每个节点有两个指针,一个指向前节点,一个指向后节点,所以双链表既可以向后查询也可以向前查询
循环链表:
首尾相连的链表即为循环链表
链表的定义
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
203.移除链表元素
题目描述
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
示例
输入: head = [1,2,6,3,4,5,6], val = 6
输出: [1,2,3,4,5]
思路
使用dummy虚拟节点,删除对应节点,最后返回dummy.next
代码
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
dummy = ListNode(next=head)
cur = dummy
while cur.next:
if cur.next.val == val:
cur.next = cur.next.next
else:
cur = cur.next
return dummy.next
707.设计链表
题目描述
设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。
示例
MyLinkedList linkedList = new MyLinkedList();
linkedList.addAtHead(1);
linkedList.addAtTail(3);
linkedList.addAtIndex(1,2); //链表变为1-> 2-> 3
linkedList.get(1); //返回2
linkedList.deleteAtIndex(1); //现在链表是1-> 3
linkedList.get(1); //返回3
思路
设立虚拟头结点再进行操作
代码
class Node:
def __init__(self, val):
self.val = val
self.next = None
class MyLinkedList:
def __init__(self):
self.head = Node(0) #虚拟头结点
self.count_ = 0 #添加的节点数
def get(self, index: int) -> int:
if 0 <= index < self.count_:
cur = self.head
for _ in range(index + 1):
cur = cur.next
return cur.val
else:
return -1
def addAtHead(self, val: int) -> None:
self.addAtIndex(0, val)
def addAtTail(self, val: int) -> None:
self.addAtIndex(self.count_, val)
def addAtIndex(self, index: int, val: int) -> None:
if index < 0:
index = 0
elif index > self.count_:
return
self.count_ += 1
add_node = Node(val)
pre_node, cur_node = None, self.head
for _ in range(index + 1):
pre_node, cur_node = cur_node, cur_node.next
else:
pre_node.next, add_node.next = add_node, cur_node
def deleteAtIndex(self, index: int) -> None:
if 0 <= index < self.count_:
self.count_ -= 1
pre_node, cur_node = None, self.head
for _ in range(index + 1):
pre_node, cur_node = cur_node, cur_node.next
else:
pre_node.next, cur_node.next = cur_node.next, None
206.反转链表
题目描述
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例
输入: head = [1,2,3,4,5]
输出: [5,4,3,2,1]
思路
首先定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。 先要把 cur->next 节点用tmp指针保存一下,也就是保存一下这个节点。
将cur->next 指向pre ,此时已经反转了第一个节点了。 继续移动pre和cur指针。
最后,cur 指针已经指向了null,循环结束,链表也反转完毕了。return pre即可,此时pre指向了新的头结点。
代码
# 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]:
cur, pre = head, None
while cur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
总结
重新复习了一遍链表,要学会灵活使用虚拟头结点,另外设计链表的每个操作都要掌握,注意细节。