707. 设计链表
题目:
要求:
你可以选择使用单链表或者双链表,设计并实现自己的链表。
单链表中的节点应该具备两个属性: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的节点。
答案:
我看题目的要求以为是要在 MyLinkedList 中包含 val 和 next,所以思路有点跑偏,所以写出来的答案比较复杂,花费的时间也比较久,不过也不算毫无收获,在我写题解的过程中,我对链表虚拟节点的使用掌握的更加熟练;另外学到的就是如果在一个问题上花费了太久,要么是非常难,要么就需要转换思路了,很明显,这道题目不难,那就需要转换思路,答案如下:
public class MyLinkedList {
private int val;
private MyLinkedList next;
private int length;
public MyLinkedList() {
length = 0;
}
public MyLinkedList(int val, int length) {
this.val = val;
this.length = length;
}
public int get(int index) {
if (index < 0 || index >= length) {
return -1;
}
MyLinkedList virtual = virtualNode();
MyLinkedList header = virtual.next;
int ind = 0;
while (ind < index) {
ind++;
header = header.next;
}
return header.val;
}
public void addAtHead(int val) {
if (length != 0) {
MyLinkedList temp = new MyLinkedList(this.val, length);
temp.next = next;
next = temp;
}
length++;
this.val = val;
}
public void addAtTail(int val) {
if (length != 0) {
MyLinkedList temp = new MyLinkedList(val, 1);
temp.next = null;
MyLinkedList virtual = next;
if (virtual == null) {
next = temp;
} else {
while (virtual.next != null) {
virtual.length++;
virtual = virtual.next;
}
virtual.next = temp;
virtual.length++;
}
} else {
this.val = val;
}
length++;
}
public void addAtIndex(int index, int val) {
if (index < 0 || index > length) {
return;
}
if (index == 0) {
addAtHead(val);
} else if (index == length) {
addAtTail(val);
} else {
// 构造添加的节点
MyLinkedList temp = new MyLinkedList(val, 1);
// 构造虚拟节点,虚拟节点的 next 为当前节点
MyLinkedList virtual = virtualNode();
MyLinkedList virtualHeader = virtual.next;
int ind = 0;
// 到目标索引的前一位
while (ind < index - 1) {
ind++;
virtualHeader.length++;
virtualHeader = virtualHeader.next;
}
// 修正指针和长度
temp.next = virtualHeader.next;
virtualHeader.next = temp;
virtualHeader.length++;
temp.length = temp.next.length + 1;
// 修正当前节点
correctTheCurrentNode(virtual);
}
}
private void correctTheCurrentNode(MyLinkedList virtual) {
if (virtual.next == null) {
this.val = 0;
this.next = null;
this.length = 0;
} else {
this.val = virtual.next.val;
this.next = virtual.next.next;
this.length = virtual.next.length;
}
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= length) {
return;
}
MyLinkedList virtual = virtualNode();
MyLinkedList virtualTwo = virtual;
int ind = 0;
// 到目标索引的前一位
while (ind < index) {
ind++;
virtualTwo = virtualTwo.next;
virtualTwo.length--;
}
virtualTwo.next = virtualTwo.next.next;
correctTheCurrentNode(virtual);
}
private MyLinkedList virtualNode() {
MyLinkedList virtual = new MyLinkedList(0, 0);
MyLinkedList virtualHeader = new MyLinkedList(this.val, length);
virtualHeader.next = next;
virtual.next = virtualHeader;
return virtual;
}
public static void main(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addAtHead(1);
myLinkedList.addAtTail(3);
myLinkedList.addAtIndex(1,2);
myLinkedList.get(1);
myLinkedList.deleteAtIndex(1);
myLinkedList.get(1);
}
}
接下来是我大致瞄了一眼官方答案写出来的答案,利用 ListNode 来实现。
class MyLinkedList {
int size;
ListNode header;
public MyLinkedList() {
size = 0;
header = null;
}
public int get(int index) {
if (index < 0 || index >= size) {
return -1;
}
ListNode temp = header;
while (index > 0) {
index --;
temp = temp.next;
}
return temp.val;
}
public void addAtHead(int val) {
ListNode temp = header;
ListNode addHeaderNode = new ListNode(val, temp);
header = addHeaderNode;
size ++;
}
public void addAtTail(int val) {
if (size == 0) {
addAtHead(val);
} else {
ListNode addTailNode = new ListNode(val);
ListNode temp = header;
while (temp.next != null) {
temp = temp.next;
}
temp.next = addTailNode;
size ++;
}
}
public void addAtIndex(int index, int val) {
if (index < 0 || index > size) {
return;
}
ListNode addTailNode = new ListNode(val);
// 构造虚拟节点
ListNode virtual = new ListNode(0, header);
ListNode temp = virtual;
int ind = 0;
while (ind < index) {
ind ++;
temp = temp.next;
}
addTailNode.next = temp.next;
temp.next = addTailNode;
size ++;
header = virtual.next;
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
size --;
// 构造虚拟节点
ListNode virtual = new ListNode(0, header);
ListNode temp = virtual;
int ind = 0;
while (ind < index) {
ind ++;
temp = temp.next;
}
if (temp.next == null) {
header = null;
return;
}
temp.next = temp.next.next;
header = virtual.next;
}
}
class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}

浙公网安备 33010602011771号