算法记录 | Day3链表基础
LeetCode 203-移除链表元素
题目描述:给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
解题思路
- 该题就是最简单的移除链表。
双指针法
# 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]:
# 虚拟头结点
pre_node = ListNode(next=head)
# print(pre_node)
node = pre_node
while node.next:
if node.next.val == val:
node.next = node.next.next
else:
node = node.next
return pre_node.next
重点
- 虚拟头节点的设置
总结
基础题,第一次做可能不知道节点的写法。
LeetCode 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, next=None):
self.val = val
self.next = next
class MyLinkedList:
def __init__(self):
# 链表在操作的时候最好设置虚拟头节点
self.head = Node(0)
self.length = 0
def get(self, index: int) -> int:
# 注意条件, 如果索引无效
if self.length >=0 and index < self.length:
p = self.head
for i in range(index+1):
p = p.next
return p.val
else:
return -1
def addAtHead(self, val: int) -> None:
# 在链表的第一个元素之前添加值为val的节点
node = Node(val)
node.next = self.head.next
self.head.next = node
# 注意,节点数要+1
self.length += 1
def addAtTail(self, val: int) -> None:
# 加到尾部
tail_node = Node(val)
p = self.head
while p.next:
p = p.next
p.next = tail_node
self.length += 1
def addAtIndex(self, index: int, val: int) -> None:
if index <= 0:
self.addAtHead(val)
return
if index == self.length:
self.addAtTail(val)
return
if index > self.length:
return
# 第index节点之前添加
node = Node(val)
p = self.head
for i in range(index):
p = p.next
node.next = p.next
p.next = node
## 忘记长度+1
self.length += 1
def deleteAtIndex(self, index: int) -> None:
if index<0 or index >= self.length:
return
p = self.head
for i in range(index):
p = p.next
p.next = p.next.next
### 忘记了长度-1...
self.length -= 1
注意:
难点
- 虚拟头节点如何设置,注意
__init__下面的写法 - 细节上,总是忘记长度+1 -1的操作
- 边界细节处理不好容易空指针
总结
这道题本身就是一些基础操作,关键难点在于处理细节上,一不小心就会出现指针指到空的位置。
LeetCode 206-反转链表
题目描述:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,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
难点
如何思考反转
总结
收获:重新复习了一遍链表的结构,细节方面还得更加仔细注意,很容易出错。