# LeetCode 203. Remove Linked List Elements
LeetCode 203. 视频讲解:手把手带你学会操作链表 | LeetCode:203.移除链表元素_哔哩哔哩_bilibili
使用添加虚拟空节点的方法,在链表中删除元素可以用两个变量(pre 和cur )遍历整个列表(也可以用一个变量cur 遍历)。一个变量pre 指代前一个元素,一个变量cur 指代当前元素。在链表中删除元素时需要知道待删除元素的前一个元素。添加虚拟空节点方法的优势是可以使用统一规则删除元素。
时间复杂度:O(n).
添加虚拟空节点方法:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
if (head == null) {
return head;
}
ListNode dummy_head = new ListNode(-1, head);
ListNode pre = dummy_head;
ListNode cur = head;
cur = dummy_head;
while (cur != null) {
if (cur.val == val) {
pre.next = cur.next;
}
else {
pre = cur;
}
cur = cur.next;
}
return dummy_head.next;
}
}
# LeetCode 707. Design Linked List
LeetCode 707. 视频讲解:帮你把链表操作学个通透!LeetCode:707.设计链表_哔哩哔哩_bilibili
根据视频用while 写的单节点循环结构,考虑的添加虚拟头节点的方法。几个接口都是实现对链表的操作,难点在于cur 指针应该指向dummy_head 还是dummy_head.next ,需要根据情况具体分析,分析点在是操作当前index 节点还是index 前一个节点。
在get 方法中,要求是获取第index 处的val,那么cur 指针指向dummy_head.next,即为头节点,返回时直接返回当前节点的val 值。
在addAtIndex 方法中,cur 指针指向的是dummy_head,因为添加链表节点是从目标位置的前一个节点考虑的。注意节点的顺序,首先将cur 的next 赋值给新节点,cur 的next 是新节点。
newNode.next = dummy_head.next;
dummy_head.next = newNode;
如果顺序错误可能造成cur 节点和cur.next 节点断开,无法在链表(非连续存储)中找到它。
单节点的解题方法:
class MyLinkedList {
class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
int size;
ListNode dummy_head;
public MyLinkedList() {
size = 0;
dummy_head = new ListNode(-1);
}
public int get(int index) {
ListNode cur = dummy_head.next;
if (index < 0 || index >= size) {
return -1;
}
while (index > 0) {
cur = cur.next;
index--;
}
return cur.val;
}
public void addAtHead(int val) {
ListNode newNode = new ListNode(val);
newNode.next = dummy_head.next;
dummy_head.next = newNode;
size++;
}
public void addAtTail(int val) {
ListNode node = new ListNode(val);
ListNode cur = dummy_head;
while (cur.next != null) {
cur = cur.next;
}
cur.next = node;
size++;
}
public void addAtIndex(int index, int val) {
if (index > size) {
return;
}
if (index < 0) {
index = 0;
}
ListNode node = new ListNode(val);
ListNode cur = dummy_head;
while (index > 0) {
cur = cur.next;
index--;
}
node.next = cur.next;
cur.next = node;
size++;
}
public void deleteAtIndex(int index) {
ListNode cur = dummy_head;
if (index < 0 || index >= size) {
return;
}
while (index > 0) {
cur = cur.next;
index--;
}
cur.next = cur.next.next;
size--;
}
}
/**
* 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);
*/
# LeetCode 206. Reverse Linked List
LeetCode 206. 视频讲解:帮你拿下反转链表 | LeetCode:206.反转链表 | 双指针法 | 递归法_哔哩哔哩_bilibili
类似上一个题目,考虑为在列表的最前端添加节点即可,注意返回值为dummy_head.next 。
使用虚拟头节点的方法:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur = new ListNode();
if (head == null) {
return head;
}
cur = head.next;
ListNode new_head = new ListNode(head.val);
ListNode dummy_head = new ListNode(-1, new_head);
while (cur != null) {
ListNode newNode = new ListNode(cur.val);
newNode.next = dummy_head.next;
dummy_head.next = newNode;
cur = cur.next;
}
return dummy_head.next;
}
}