一、删除链表元素
思路:无非就是找到等于val的节点,cur.next = cur.next.next; 加一个虚拟节点更好判断,不需要单独判断头节点。
class Solution {
public ListNode removeElements(ListNode head, int val) {
if (head == null) {
return head;
}
ListNode header = new ListNode(-1, head);//加一个虚拟节点
ListNode cur = header;
while (cur.next != null) {
if (cur.next.val == val) {
cur.next = cur.next.next;
}else {
cur = cur.next;
}
}
return header.next;
}
}
二、反转链表
思路:定义pre和cur分别指向前继节点和当前节点,每次将cur指向pre,达到反转的效果,如下图所示。
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null) {
return head;
}
ListNode cur = head;
ListNode pre = null;
ListNode temp;
while (cur != null) {
temp = cur.next; //保存后继节点防止断链
cur.next = pre; //反转链表
pre = cur; //下一个节点
cur = temp;
}
return pre;
}
}
递归写法:递归法相对抽象一些,但是其实和双指针法是一样的逻辑,同样是当cur为空的时候循环结束,不断将cur指向pre的过程。
class Solution {
public ListNode reverseList(ListNode head) {
return reverse(null, head);
}
private ListNode reverse(ListNode pre, ListNode cur) {
if (cur == null) {
return pre;
}
ListNode temp = cur.next;//同样保存后继
cur.next = pre;
return reverse(cur, temp);
}
}