设计链表
设计链表
你可以选择使用单链表或者双链表,设计并实现自己的链表。
单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。
如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。
实现 MyLinkedList 类:
MyLinkedList() 初始化 MyLinkedList 对象。
int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。
Python
解一:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class MyLinkedList:
def __init__(self):
self.head = None
self.length = 0
def get(self, index: int) -> int:
if index < 0 or index >= self.length:
return -1
current = self.head
for i in range(index):
current = current.next
return current.val
def addAtHead(self, val: int) -> None:
node = ListNode(val, self.head)
self.head = node
self.length += 1
def addAtTail(self, val: int) -> None:
if not self.head:
self.head = ListNode(val)
else:
current = self.head
while current.next:
current = current.next
current.next = ListNode(val)
self.length += 1
def addAtIndex(self, index: int, val: int) -> None:
if index > self.length:
return
elif index <= 0:
self.addAtHead(val)
elif index == self.length:
self.addAtTail(val)
else:
current = self.head
for i in range(index - 1):
current = current.next
node = ListNode(val, current.next)
current.next = node
self.length += 1
def deleteAtIndex(self, index: int) -> None:
if index < 0 or index >= self.length:
return
if index == 0:
self.head = self.head.next
else:
current = self.head
for i in range(index - 1):
current = current.next
current.next = current.next.next
self.length -= 1
解二:
class Node(object):
def __init__(self, x=0):
self.val = x
self.next = None
class MyLinkedList(object):
def __init__(self):
self.head = Node()
self.size = 0 # 设置一个链表长度的属性,便于后续操作,注意每次增和删的时候都要更新
def get(self, index):
"""
:type index: int
:rtype: int
"""
if index < 0 or index >= self.size:
return -1
cur = self.head.next
while(index):
cur = cur.next
index -= 1
return cur.val
def addAtHead(self, val):
"""
:type val: int
:rtype: None
"""
new_node = Node(val)
new_node.next = self.head.next
self.head.next = new_node
self.size += 1
def addAtTail(self, val):
"""
:type val: int
:rtype: None
"""
new_node = Node(val)
cur = self.head
while(cur.next):
cur = cur.next
cur.next = new_node
self.size += 1
def addAtIndex(self, index, val):
"""
:type index: int
:type val: int
:rtype: None
"""
if index < 0:
self.addAtHead(val)
return
elif index == self.size:
self.addAtTail(val)
return
elif index > self.size:
return
node = Node(val)
pre = self.head
while(index):
pre = pre.next
index -= 1
node.next = pre.next
pre.next = node
self.size += 1
def deleteAtIndex(self, index):
"""
:type index: int
:rtype: None
"""
if index < 0 or index >= self.size:
return
pre = self.head
while(index):
pre = pre.next
index -= 1
pre.next = pre.next.next
self.size -= 1
笔记
- 这道题目思路不难,但是需要注意的细节很多,例如在首端增添元素,原链表为空等等,需要全方面地考虑;
- 要善于利用python的一些语法,例如链表中指针的移动可以借助for循环实现(如题1);
- 除了单链表外,还可以考虑双链表(相对于单链表,多了prev属性);
- 对链表的操作可以考虑使用虚拟结点(如解2)会比解一方便些(例如链表为空的情况不需要特别处理)。
浙公网安备 33010602011771号