文档讲解:代码随想录 (programmercarl.com)
视频讲解:手把手带你学会操作链表 | LeetCode:203.移除链表元素_哔哩哔哩_bilibili
203. 移除链表元素 - 力扣(LeetCode)
思路:
不能对空节点进行操作,因此要检验是否为空
头节点可能也要被移除,要使用while循环来移除
将头节点赋值给另一个指针,由另一个指针去遍历链表,删除元素
// 看视频以前的思路
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode node = head;
if(node == null)return node;
while(node.val == val){
node = node.next;
head = node;
if(node == null)return node;
}
while(node != null){
if(node.next == null)break;
ListNode fast = node.next;
while(fast != null && fast.val == val)fast = fast.next;
if(fast == null)node.next = null;
else node.next = fast;
node = node.next;
}
return head;
}
}
// 时间复杂度: O(n)
// 空间复杂度: O(1)
// 视频中第一种解法
class Solution {
public ListNode removeElements(ListNode head, int val) {
while(head != null && head.val == val)head = head.next;
ListNode cur = head;
while(cur != null && cur.next != null){
if(cur.next.val == val)cur.next = cur.next.next;
else cur = cur.next;
}
return head;
}
}
虚拟头节点方法:设置一个虚拟头节点,next指向head,便于对链表进行统一操作
// 时间复杂度: O(n)
// 空间复杂度: O(1)
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode dummyhead = new ListNode();
dummyhead.next = head;
ListNode cur = dummyhead;
while(cur.next != null) {
if(cur.next.val == val)cur.next = cur.next.next;
else cur = cur.next;
}
return dummyhead.next;
}
}
// 自己的想法
class ListNode { // 链表节点
int val;
ListNode next;
public ListNode(){}
}
class MyLinkedList {
ListNode dummyhead; // 虚拟头节点
public MyLinkedList() {
dummyhead = new ListNode();
}
public int get(int index) {
ListNode cur = dummyhead.next; // cur.val就是这个函数要找的值
while(index > 0 && cur != null) {
cur = cur.next;
index--;
}
if(index < 0 || cur == null)return -1; // index < 0意味着index输入值是负数
// index >= 0但cur为null意味着index大于链表的长度
return cur.val;
}
public void addAtHead(int val) {
ListNode head = new ListNode();
head.val = val;
head.next = dummyhead.next;
dummyhead.next = head;
}
public void addAtTail(int val) {
ListNode cur = dummyhead;
while(cur.next != null){
cur = cur.next;
}
ListNode end = new ListNode();
end.val = val;
cur.next = end;
}
public void addAtIndex(int index, int val) {
ListNode cur = dummyhead;
while(index > 0 && cur.next != null) {
cur = cur.next;
index--;
}
// index != 0 && cur.next == null 代表index超过了链表的长度
if(index != 0 && cur.next == null || index < 0)return;
ListNode addnode = new ListNode();
addnode.val = val;
addnode.next = cur.next;
cur.next = addnode;
}
public void deleteAtIndex(int index) {
ListNode cur = dummyhead;
while(index > 0 && cur.next != null){
cur = cur.next;
index--;
}
if(cur.next == null || index < 0)return;
cur.next = cur.next.next;
}
}
/**
* 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);
*/
// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
public ListNode reverseList(ListNode head) {
ListNode fast = head;
ListNode slow = null;
while(fast != null) {
ListNode node = fast.next;
fast.next = slow;
slow = fast;
fast = node;
}
return slow;
}
}
递归:
// 时间复杂度O(n)
// 空间复杂度O(n)
class Solution {
public ListNode reverseList(ListNode head) {
return reverse(null, head);
}
public ListNode reverse(ListNode pre, ListNode cur) {
if(cur == null)return pre;
ListNode node = cur.next;
cur.next = pre;
return reverse(cur, node);
}
}
从后向前递归:
// 时间复杂度O(n)
// 空间复杂度O(n)
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null)return null;
if(head.next == null)return head;
ListNode last = reverseList(head.next);
head.next.next = head;
head.next = null;
return last;
}
}