707. 设计链表
设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val
和 next
。val
是当前节点的值,next
是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev
以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。
在链表类中实现这些功能:
index
个节点的值。如果索引无效,则返回-1
。val
的节点。插入后,新节点将成为链表的第一个节点。val
的节点追加到链表的最后一个元素。index
个节点之前添加值为 val
的节点。如果 index
等于链表的长度,则该节点将附加到链表的末尾。如果 index
大于链表长度,则不会插入节点。如果index
小于0,则在头部插入节点。index
有效,则删除链表中的第 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
提示:
val
值都在 [1, 1000]
之内。[1, 1000]
之内。原站题解
golang 解法, 执行用时: 24 ms, 内存消耗: 7.4 MB, 提交时间: 2023-06-25 10:44:38
type node struct { val int next, prev *node } type MyLinkedList struct { head, tail *node size int } func Constructor() MyLinkedList { head := &node{} tail := &node{} head.next = tail tail.prev = head return MyLinkedList{head, tail, 0} } func (l *MyLinkedList) Get(index int) int { if index < 0 || index >= l.size { return -1 } var curr *node if index+1 < l.size-index { curr = l.head for i := 0; i <= index; i++ { curr = curr.next } } else { curr = l.tail for i := 0; i < l.size-index; i++ { curr = curr.prev } } return curr.val } func (l *MyLinkedList) AddAtHead(val int) { l.AddAtIndex(0, val) } func (l *MyLinkedList) AddAtTail(val int) { l.AddAtIndex(l.size, val) } func (l *MyLinkedList) AddAtIndex(index, val int) { if index > l.size { return } index = max(0, index) var pred, succ *node if index < l.size-index { pred = l.head for i := 0; i < index; i++ { pred = pred.next } succ = pred.next } else { succ = l.tail for i := 0; i < l.size-index; i++ { succ = succ.prev } pred = succ.prev } l.size++ toAdd := &node{val, succ, pred} pred.next = toAdd succ.prev = toAdd } func (l *MyLinkedList) DeleteAtIndex(index int) { if index < 0 || index >= l.size { return } var pred, succ *node if index < l.size-index { pred = l.head for i := 0; i < index; i++ { pred = pred.next } succ = pred.next.next } else { succ = l.tail for i := 0; i < l.size-index-1; i++ { succ = succ.prev } pred = succ.prev.prev } l.size-- pred.next = succ succ.prev = pred } func max(a, b int) int { if b > a { return b } return a } /** * Your MyLinkedList object will be instantiated and called as such: * obj := Constructor(); * param_1 := obj.Get(index); * obj.AddAtHead(val); * obj.AddAtTail(val); * obj.AddAtIndex(index,val); * obj.DeleteAtIndex(index); */
python3 解法, 执行用时: 100 ms, 内存消耗: 17.7 MB, 提交时间: 2023-06-25 10:44:10
# 双链表 class ListNode: def __init__(self, x): self.val = x self.next = None self.prev = None class MyLinkedList: def __init__(self): self.size = 0 self.head, self.tail = ListNode(0), ListNode(0) self.head.next = self.tail self.tail.prev = self.head def get(self, index: int) -> int: if index < 0 or index >= self.size: return -1 if index + 1 < self.size - index: curr = self.head for _ in range(index + 1): curr = curr.next else: curr = self.tail for _ in range(self.size - index): curr = curr.prev return curr.val def addAtHead(self, val: int) -> None: self.addAtIndex(0, val) def addAtTail(self, val: int) -> None: self.addAtIndex(self.size, val) def addAtIndex(self, index: int, val: int) -> None: if index > self.size: return index = max(0, index) if index < self.size - index: pred = self.head for _ in range(index): pred = pred.next succ = pred.next else: succ = self.tail for _ in range(self.size - index): succ = succ.prev pred = succ.prev self.size += 1 to_add = ListNode(val) to_add.prev = pred to_add.next = succ pred.next = to_add succ.prev = to_add def deleteAtIndex(self, index: int) -> None: if index < 0 or index >= self.size: return if index < self.size - index: pred = self.head for _ in range(index): pred = pred.next succ = pred.next.next else: succ = self.tail for _ in range(self.size - index - 1): succ = succ.prev pred = succ.prev.prev self.size -= 1 pred.next = succ succ.prev = pred # Your MyLinkedList object will be instantiated and called as such: # obj = MyLinkedList() # param_1 = obj.get(index) # obj.addAtHead(val) # obj.addAtTail(val) # obj.addAtIndex(index,val) # obj.deleteAtIndex(index)
python3 解法, 执行用时: 148 ms, 内存消耗: 16.9 MB, 提交时间: 2023-06-25 10:43:16
class ListNode: def __init__(self, val): self.val = val self.next = None class MyLinkedList: def __init__(self): self.size = 0 self.head = ListNode(0) def get(self, index: int) -> int: if index < 0 or index >= self.size: return -1 cur = self.head for _ in range(index + 1): 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.size, val) def addAtIndex(self, index: int, val: int) -> None: if index > self.size: return index = max(0, index) self.size += 1 pred = self.head for _ in range(index): pred = pred.next to_add = ListNode(val) to_add.next = pred.next pred.next = to_add def deleteAtIndex(self, index: int) -> None: if index < 0 or index >= self.size: return self.size -= 1 pred = self.head for _ in range(index): pred = pred.next pred.next = pred.next.next # Your MyLinkedList object will be instantiated and called as such: # obj = MyLinkedList() # param_1 = obj.get(index) # obj.addAtHead(val) # obj.addAtTail(val) # obj.addAtIndex(index,val) # obj.deleteAtIndex(index)
javascript 解法, 执行用时: 124 ms, 内存消耗: 49 MB, 提交时间: 2023-06-25 10:42:45
var MyLinkedList = function() { this.size = 0; this.head = new ListNode(0); }; /** * @param {number} index * @return {number} */ MyLinkedList.prototype.get = function(index) { if (index < 0 || index >= this.size) { return -1; } let cur = this.head; for (let i = 0; i <= index; i++) { cur = cur.next; } return cur.val; }; /** * @param {number} val * @return {void} */ MyLinkedList.prototype.addAtHead = function(val) { this.addAtIndex(0, val); }; /** * @param {number} val * @return {void} */ MyLinkedList.prototype.addAtTail = function(val) { this.addAtIndex(this.size, val); }; /** * @param {number} index * @param {number} val * @return {void} */ MyLinkedList.prototype.addAtIndex = function(index, val) { if (index > this.size) { return; } index = Math.max(0, index); this.size++; let pred = this.head; for (let i = 0; i < index; i++) { pred = pred.next; } let toAdd = new ListNode(val); toAdd.next = pred.next; pred.next = toAdd; }; /** * @param {number} index * @return {void} */ MyLinkedList.prototype.deleteAtIndex = function(index) { if (index < 0 || index >= this.size) { return; } this.size--; let pred = this.head; for (let i = 0; i < index; i++) { pred = pred.next; } pred.next = pred.next.next; }; function ListNode(val, next) { this.val = (val===undefined ? 0 : val) this.next = (next===undefined ? null : next) } /** * Your MyLinkedList object will be instantiated and called as such: * var obj = new MyLinkedList() * var param_1 = obj.get(index) * obj.addAtHead(val) * obj.addAtTail(val) * obj.addAtIndex(index,val) * obj.deleteAtIndex(index) */
golang 解法, 执行用时: 16 ms, 内存消耗: 7.4 MB, 提交时间: 2023-06-25 10:40:48
type MyLinkedList struct { dummy *ListNode // 内置数据结构 cnt int } func Constructor() MyLinkedList { return MyLinkedList{&ListNode{}, 0} } func (this *MyLinkedList) Get(index int) int { if index < 0 || index >= this.cnt { return -1 } cur := this.dummy.Next for ; index > 0; index-- { cur = cur.Next } return cur.Val } func (this *MyLinkedList) AddAtHead(val int) { this.AddAtIndex(0, val) } func (this *MyLinkedList) AddAtTail(val int) { this.AddAtIndex(this.cnt, val) } func (this *MyLinkedList) AddAtIndex(index int, val int) { if index > this.cnt { return } pre := this.dummy for ; index > 0; index-- { pre = pre.Next } pre.Next = &ListNode{val, pre.Next} this.cnt++ } func (this *MyLinkedList) DeleteAtIndex(index int) { if index < 0 || index >= this.cnt { return } pre := this.dummy for ; index > 0; index-- { pre = pre.Next } t := pre.Next pre.Next = t.Next t.Next = nil this.cnt-- } /** * Your MyLinkedList object will be instantiated and called as such: * obj := Constructor(); * param_1 := obj.Get(index); * obj.AddAtHead(val); * obj.AddAtTail(val); * obj.AddAtIndex(index,val); * obj.DeleteAtIndex(index); */
java 解法, 执行用时: 11 ms, 内存消耗: 43.2 MB, 提交时间: 2023-06-25 10:40:17
class MyLinkedList { private ListNode dummy = new ListNode(); private int cnt; public MyLinkedList() { } public int get(int index) { if (index < 0 || index >= cnt) { return -1; } var cur = dummy.next; while (index-- > 0) { cur = cur.next; } return cur.val; } public void addAtHead(int val) { addAtIndex(0, val); } public void addAtTail(int val) { addAtIndex(cnt, val); } public void addAtIndex(int index, int val) { if (index > cnt) { return; } var pre = dummy; while (index-- > 0) { pre = pre.next; } pre.next = new ListNode(val, pre.next); ++cnt; } public void deleteAtIndex(int index) { if (index < 0 || index >= cnt) { return; } var pre = dummy; while (index-- > 0) { pre = pre.next; } var t = pre.next; pre.next = t.next; t.next = null; --cnt; } } /** * Your MyLinkedList object will be instantiated and called as such: * MyLinkedList obj = new MyLinkedList(); * int param_1 = obj.get(index); * obj.addAtHead(val); * obj.addAtTail(val); * obj.addAtIndex(index,val); * obj.deleteAtIndex(index); */
python3 解法, 执行用时: 140 ms, 内存消耗: 16.9 MB, 提交时间: 2023-06-25 10:39:27
# 我们创建链表虚拟头节点 dummy,用变量 cnt 记录当前链表节点个数。 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 # Your MyLinkedList object will be instantiated and called as such: # obj = MyLinkedList() # param_1 = obj.get(index) # obj.addAtHead(val) # obj.addAtTail(val) # obj.addAtIndex(index,val) # obj.deleteAtIndex(index)