203. Remove Linked List Elements
题目链接:203. Remove Linked List Elements
思路链接:代码随想录链表-移除链表元素
思路
原链表删除法:需要注意删除头节点的方式与删除非头节点的方式不一样
虚拟节点法:通过在头节点处加入虚拟节点,可以规避掉原链表删除法的问题
心路历程
对于链表也已经开始遗忘,一开始没做出来,看了视频文章之后发现好简单
Code
/**
* 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) {
// 原链表删除方法
// 删除head节点
while (head != null && head.val == val) { // 注意要使用while,因为删除了head节点后的下一个head节点可能也要删
head = head.next;
}
// 删除中间节点
ListNode curr = head; // 定义一个临时指针来遍历链表,注意要指向head,因为是单向链表,删除一个节点需要找到上一个节点
while (curr != null && curr.next != null) {
if (curr.next.val == val) {
curr.next = curr.next.next;
} else {
curr = curr.next;
}
}
return head;
}
}
/**
* 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) {
// 虚拟节点法
ListNode dummy = new ListNode(); // 定义虚拟节点
dummy.next = head;
ListNode curr = dummy; // 定义临时节点,注意要指向虚拟节点,因为删除节点需要找上一个节点
while (curr.next != null) {
if (curr.next.val == val) {
curr.next = curr.next.next;
} else {
curr = curr.next;
}
}
return dummy.next; // 不能指向head,因为head 可能被删了
}
}
707. Design Linked List
题目链接:707. Design Linked List
思路链接:代码随想录链表-设计链表
思路
可以使用单链表和双链表,就是普通的构造,不难,可以尝试虚拟节点的方法来增删
心路历程
有点生疏了,调试了很久,只写了单链表的解法
Code
// 单向链表
class ListNode {
int val;
ListNode next;
public ListNode(){}
public ListNode(int val) {
this.val = val;
this.next = null;
}
}
class MyLinkedList {
int size;
ListNode head;
public MyLinkedList() {
this.size = 0;
this.head = null;
}
public int get(int index) {
if (index > size - 1 || index < 0) {
return -1;
}
ListNode curr = head;
while (index > 0) { // 考虑极端情况就可以判断while里面的条件是否正确,index = 0时
curr = curr.next;
index--;
}
return curr.val;
}
public void addAtHead(int val) {
ListNode newNode = new ListNode(val);
newNode.next = head;
head = newNode;
size++;
}
public void addAtTail(int val) {
ListNode newNode = new ListNode(val);
if (size == 0) {
head = newNode;
} else {
ListNode curr = head;
while (curr.next != null) {
curr = curr.next;
}
curr.next = newNode;
}
size++;
}
public void addAtIndex(int index, int val) {
if (index > size || index < 0) {
return;
} else if (index == 0) {
addAtHead(val);
} else if (index == size) {
addAtTail(val);
} else {
ListNode curr = head;
ListNode newNode = new ListNode(val);
for (int i = 0; i < index - 1; i++) { // 注意一定要使curr指向index - 1,指向index的是curr.next
curr = curr.next;
}
newNode.next = curr.next; // 注意顺序!
curr.next = newNode;
size++;
}
}
public void deleteAtIndex(int index) {
if (index >= size || index < 0) {
return;
}
size--;
if (index == 0) {
head = head.next;
} else {
ListNode curr = head;
while (index - 1 > 0) { // 注意一定要使curr指向index - 1,指向index的是curr.next
curr = curr.next;
index--;
}
curr.next = curr.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);
*/
203. Remove Linked List Elements
题目链接:206. Reverse Linked List
思路链接:代码随想录链表-反转链表
思路
双指针法:定义pre与curr两个指针,每一个循环将curr.next反指向pre,然后将pre,curr向前挪,最后当curr为null时结束循环,return pre。注意要再定义一个临时指针来储存原来的curr.next。递归写法思路和迭代写法一样,是根据迭代写法改写的
心路历程
之前遇到过,也没做出来,看了解法也没理解。这次看了卡哥的视频和文章算是彻底理解了。
Code
/**
* 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 curr = head; // 初始化指针,到后来要将curr.next倒指向pre
ListNode pre = null;
while (curr != null) {
ListNode temp = curr.next; // 定义一个临时指针,为了防止curr指向pre时丢失curr.next
curr.next = pre; // 使curr指向pre
pre = curr; // 注意要先更新pre,如果先更新curr,会导致pre无法更新
curr = temp;
}
return pre;
}
}
/**
* 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 {
// 递归写法
private ListNode reverseHelper(ListNode pre, ListNode curr) {
if (curr == null) {
return pre;
} else {
ListNode temp = curr.next; // 定义临时指针
curr.next = pre; // curr指向pre,完成这一轮的工作
return reverseHelper(curr, temp); // 将curr赋值给pre,将temp给curr,起到了更新curr和pre的作用
}
}
public ListNode reverseList(ListNode head) {
return reverseHelper(null, head);
}
}