203. 移除链表元素
题目描述:给你一个链表的头节点
head和一个整数val,请你删除链表中所有满足Node.val == val的节点,并返回 新的头节点 。
解题思路:
- 要删除
val,则不能是空列表且列表需要有val值。要做好空值判断。 - 考虑到如果val在头节点位置,需要单独判断。而添加
dummy头节点可以避免单独判断。 - 最简单的直接解法就是迭代。从理论上讲,迭代法都可以改写成递归法。且链表具有天然的递归性,所以递归法也可以考虑。
一、迭代法
# 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]:
if not head:
return
dummy = ListNode(next=head)
p = dummy
while p.next:
if p.next.val == val:
p.next = p.next.next
else:
p = p.next
return dummy.next
二、递归法
class Solution:
def removeElements(self, head: ListNode, val: int) -> ListNode:
if not head: return
head.next = self.removeElements(head.next, val)
return head.next if head.val == val else head
707. 设计链表
题目描述:设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:
val和next。val是当前节点的值,next是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性prev以指示链表中的上一个节点。假设链表中的所有节点都是0-index的。
在链表类中实现这些功能:
get(index):获取链表中第index个节点的值。如果索引无效,则返回-1
addAtHead(val):在链表的第一个元素之前添加一个值为val的节点。插入后,新节点将成为链表的第一个节点。
addAtTail(val):将值为val的节点追加到链表的最后一个元素
addAtIndex(index,val):在链表中的第index个节点之前添加值为val的节点。如果index等于链表的长度,则该节点将附加到链表的末尾。如果index大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
deleteAtIndex(index):如果索引index有效,则删除链表中的第index个节点。
解题思路:基础题,正常做,常做常新。为了不特别判断头节点可以设置dummy头节点。
class LinkNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class MyLinkedList:
def __init__(self):
self.dummy = LinkNode()
self.size = 0
def get(self, index: int) -> int:
if index < 0 or index >= self.size:
return -1
cur = self.dummy.next
while index:
cur = cur.next
index -= 1
return cur.val
def addAtHead(self, val: int) -> None:
new_node = LinkNode(val=val, next=self.dummy.next)
self.dummy.next = new_node
self.size += 1
def addAtTail(self, val: int) -> None:
new_node = LinkNode(val=val)
cur = self.dummy
while cur.next:
cur = cur.next
cur.next = new_node
self.size += 1
def addAtIndex(self, index: int, val: int) -> None:
if index <= 0:
self.addAtHead(val=val)
return
elif index > self.size:
return
elif index == self.size:
self.addAtTail(val)
return
cur = self.dummy
while index:
cur = cur.next
index -= 1
new_node = LinkNode(val=val, next=cur.next)
cur.next = new_node
self.size += 1
return
def deleteAtIndex(self, index: int) -> None:
if index < 0 or index >= self.size:
return
cur = self.dummy
while index:
cur = cur.next
index -= 1
cur.next = cur.next.next
self.size -= 1
return
206. 反转链表
题目描述:给你单链表的头节点
head,请你反转链表,并返回反转后的链表。
解题思路:很明显一个指针不够用,要用双指针。cur指针指向头节点,pre指针初始化为空指针,先用中间变量tmp指针储存cur.next,接着开始反转,cur.next指向pre所指的位置,pre指向cur所指的位置,cur指向tmp所指的位置。
# 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]:
pre = None
cur = head
while cur: # 不能是cur.next,因为cur.next指向pre了
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre