題目描述:
設計鏈表的實現。您可以選擇使用單鏈表或雙鏈表。單鏈表中的節點應該具有兩個屬性: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
個節點。
示例:
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]
之內。 - 請不要使用內置的 LinkedList 庫。
解法:雙鏈表
每個節點有兩個指針,一個指向上一個節點,一個指向下一個節點。
代碼:
class MyLinkedList {
Node head;
Node tail;
Integer len;
class Node {
int val;
Node prev;
Node next;
public Node(int val) {
this.val = val;
}
}
public MyLinkedList() {
head = new Node(0);
tail = new Node(0);
head.next = tail;
tail.prev = head;
len = 0;
}
public int get(int index) {
if (index < 0 || index >= len) {
return -1;
}
Node h = head;
for(int i = 0;i<=index;i++) {
h = h.next;
}
return h.val;
}
public void addAtHead(int val) {
addAtIndex(0,val);
}
public void addAtTail(int val) {
addAtIndex(len,val);
}
public void addAtIndex(int index, int val) {
if(index > len) {
return;
}
index = Math.max(0,index);
Node node = new Node(val);
Node pred = head, succ;
for(int i = 0;i<index;i++) {
pred = pred.next;
}
succ = pred.next;
len++;
node.prev = pred;
node.next = succ;
pred.next = node;
succ.prev = node;
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= len) {
return;
}
Node pred = head, succ;
for(int i = 0;i<index;i++) {
pred = pred.next;
}
succ = pred.next.next;
len--;
pred.next = succ;
succ.prev = pred;
}
}
/**
* 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);
*/