2.力扣题目:707. 设计链表
解析:(链表常规操作)
题目要求:实现链表从头插入,从尾插入,按照索引插入,删除,查找的功能
本题不涉及特定的算法思想,但是已经覆盖了链表的常见操作。
还需要另外定义一个ListNode类实现结点的结构。本题的MyLinkedList类只是进行实现操作。
由于涉及了删除操作,所以需要使用虚拟头结点。
注意点:
注意类内全局变量,可能被任何类内的函数修改。
对于类内全局变量size,在调用addAtIndex()时,如果在addAtIndex()中调用了addHead()/addTail()函数,size在它们中已经size++过了,不能再在addAtIndex()中重复++。
代码:
// 定义单链表
class ListNode {
int val;
ListNode next;
public ListNode(){}
public ListNode(int val) {
this.val = val;
}
public ListNode(int val, ListNode next) {
this.next = next;
this.val = val;
}
}
class MyLinkedList {
int val;
ListNode next;
ListNode dummy; //虚拟头结点
int size; // 不包含虚拟头结点的实际长度
// 初始化链表
public MyLinkedList() {
size = 0;
next = null;
dummy = null;
}
public int get(int index) {
if (index < 0 || index >= size) return -1;
ListNode cur = dummy.next; // dummy.next指向的才是实际的头结点
for(int i = 0; i < index; i++) {
cur = cur.next;
}
return cur.val;
}
public void addAtHead(int val) {
if (dummy == null) {
ListNode node = new ListNode(val, null);
dummy = new ListNode(-1, node);
}
else {
ListNode node = new ListNode(val, dummy.next);
dummy.next = node;
}
size++;
}
public void addAtTail(int val) {
if (dummy == null) {
ListNode node = new ListNode(val, null);
dummy = new ListNode(-1, node);
}
else {
ListNode pre = dummy;
ListNode cur = dummy.next;
while (cur != null) {
pre = pre.next;
cur = cur.next;
}
ListNode node = new ListNode(val, null);
pre.next = node;
}
size++;
}
public void addAtIndex(int index, int val) {
if (index > size) return;
//注意 调用addHead后,在addHead里已经size++,这里就不能重复size++
else if (index <= 0) addAtHead(val);
else if (index == size) addAtTail(val);// 注意同上
else {
ListNode pre = dummy;
for (int i = 0; i < index; i++)
pre = pre.next;
ListNode node = new ListNode(val, pre.next);
pre.next = node;
size++; // 所以这里的size++必须放到这个{}内
}
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) return;
ListNode pre = dummy;
for (int i = 0; i < index; i++)
pre = pre.next;
pre.next = pre.next.next;
size--;
}
}