设计链表
难度:
标签:
题目描述
代码结果
运行时间: 208 ms, 内存: 15.8 MB
/*
* This is a solution for implementing a singly linked list using Java Streams.
* Note that Java Streams are not typically used for this type of problem, but we'll use them where applicable.
*/
import java.util.stream.IntStream;
class MyLinkedList {
private class Node {
int val;
Node next;
Node(int val) {
this.val = val;
}
}
private Node head;
private int size;
public MyLinkedList() {
head = null;
size = 0;
}
public int get(int index) {
if (index < 0 || index >= size) {
return -1;
}
Node[] node = {head};
IntStream.range(0, index).forEach(i -> node[0] = node[0].next);
return node[0].val;
}
public void addAtHead(int val) {
Node newNode = new Node(val);
newNode.next = head;
head = newNode;
size++;
}
public void addAtTail(int val) {
Node newNode = new Node(val);
if (head == null) {
head = newNode;
} else {
Node current = head;
while (current.next != null) {
current = current.next;
}
current.next = newNode;
}
size++;
}
public void addAtIndex(int index, int val) {
if (index < 0 || index > size) {
return;
}
if (index == 0) {
addAtHead(val);
} else {
Node newNode = new Node(val);
Node[] node = {head};
IntStream.range(0, index - 1).forEach(i -> node[0] = node[0].next);
newNode.next = node[0].next;
node[0].next = newNode;
size++;
}
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
if (index == 0) {
head = head.next;
} else {
Node[] node = {head};
IntStream.range(0, index - 1).forEach(i -> node[0] = node[0].next);
node[0].next = node[0].next.next;
}
size--;
}
}
解释
方法:
此题解实现了一个基本的单链表结构。类 ListNode 定义了链表的节点,包含节点值和指向下一个节点的指针。MyLinkedList 类则提供了链表的各种操作。初始化时创建一个虚拟头节点(dummy node)来简化边界条件处理。增加、删除和获取节点时都是通过遍历到目标位置来完成相应的操作。addAtHead 和 addAtTail 是特殊情况的 addAtIndex,分别在头部和尾部插入节点。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在`MyLinkedList`类中,为什么选择使用虚拟头节点(dummy node)而不是直接使用实际的头节点?
▷🦆
为什么`addAtIndex`方法在插入时需要检查`index`是否大于链表当前的长度,而不是等于或大于?
▷🦆
在执行`deleteAtIndex`操作时,如何确保在删除节点后链表的所有其他节点依然保持正确的连接状态?
▷🦆
如何处理在`addAtIndex`和`deleteAtIndex`方法中的边界情况,例如插入到链表的开始和结束位置?
▷