3-1.203题移除链表元素
题目
思路
考查单链表的删除操作,定义虚拟头结点
代码
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode dummyNode = new ListNode(-1, head); //设置虚拟头结点
ListNode pre = dummyNode;
ListNode cur = head;
while (cur != null){
if (cur.val == val){ //删除操作
pre.next = cur.next;
}
else{
pre = cur;
}
cur = cur.next;
}
return dummyNode.next;
}
}
总结
时间复杂度为
O
(
n
)
O(n)
O(n)
空间复杂度为
O
(
1
)
O(1)
O(1)
2-2.707题设计链表
题目
思路
实现单链表的初始化、查询、插入、删除操作
代码
class ListNode {
int val;
ListNode next;
ListNode(){}
ListNode(int val){
this.val = val;
}
}
class MyLinkedList {
int size; //存储链表元素个数
ListNode head; //虚拟头结点
//初始化 MyLinkedList 对象
public MyLinkedList() {
size = 0;
head = new ListNode(0); //虚拟头结点
}
//获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1
public int get(int index) {
if (index < 0 || index >= size){
return -1;
}
ListNode p = head;
//包含虚拟头结点,所以查找第 index+1 个结点
for (int i = 0; i <= index; i++){
p = p.next;
}
return p.val;
}
//将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
public void addAtHead(int val) {
//在链表最前面插入一个节点,等价于在第0个元素前添加
addAtIndex(0, val);
}
//将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
public void addAtTail(int val) {
//在链表的最后插入一个节点,等价于在(末尾+1)个元素前添加
addAtIndex(size, val);
}
public void addAtIndex(int index, int val) {
if (index > size) {
return;
}
if (index < 0){
index = 0;
}
size++; //链表长度加1
ListNode p = head;
//找到要插入结点的前驱
for (int i = 0; i < index; i++) {
p = p.next;
}
ListNode newNode = new ListNode(val);
newNode.next = p.next;
p.next = newNode;
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= size){
return;
}
size--; //链表长度减1
if (index == 0) {
head = head.next;
return;
}
//找到要插入结点的前驱
ListNode p = head;
for (int i = 0; i < index; i++) {
p = p.next;
}
p.next = p.next.next;
}
}
总结
时间复杂度: 涉及 index 的相关操作为
O
(
i
n
d
e
x
)
O(index)
O(index), 其余为
O
(
1
)
O(1)
O(1)
空间复杂度:
O
(
n
)
O(n)
O(n)
3-3.206题反转链表
题目
思路
实质上是改变链表指向
代码
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
ListNode tmp = null;
while (cur != null){
tmp = cur.next; //保存下一个结点
cur.next = pre;
pre = cur; //pre前移
cur = tmp; //cur前移
}
return pre;
}
}
//使用虚拟头结点解决链表反转
class Solution {
public ListNode reverseList(ListNode head) {
ListNode dummyHead = new ListNode(-1);
dummyHead.next = null;
ListNode cur = head;
while (cur != null){
ListNode tmp = cur.next;
cur.next = dummyHead.next;
dummyHead.next = cur;
cur = tmp;
}
return dummyHead.next;
}
}
总结
时间复杂度为
O
(
n
)
O(n)
O(n)
空间复杂度为
O
(
1
)
O(1)
O(1)
虚拟头结点YYDS!