LeetCode 203.移除链表元素
思路:使用一个哨兵节点作为头节点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 removeElements(ListNode head, int val) {
if (head == null) {
return null;
}
ListNode dummy = new ListNode(Integer.MIN_VALUE);
dummy.next = head;
ListNode root = dummy;
while (dummy.next != null) {
if (dummy.next.val == val) {
dummy.next = dummy.next.next;
} else {
dummy = dummy.next;
}
}
return root.next;
}
}
遇到的问题:一开始想不起来如何解决要删除的点正好在头结点的情况,代码存在局限性不能通过所有的case,然后就想到了利用哨兵节点,这样就能够保证在用同一种删除模式下删除原有头节点;另外,看了卡哥网站的题解后,也能够不使用哨兵节点解决问题,先把头结点是需要移除元素的情况做处理,然后再走一般的删除节点逻辑。
LeetCode 707.设计链表
思路:按照题目要求来实现,注意边界条件,需要很小心。关于链表删除部分是可以直接利用的。
代码:
class MyLinkedList {
int size;
ListNode head;
public MyLinkedList() {
size = 0;
head = new ListNode(0);
}
public int get(int index) {
if (index < 0 || index >= size) {
return -1;
}
ListNode cur = head;
for (int i = 0; i <= index; i++) {
cur = cur.next;
}
return cur.val;
}
public void addAtHead(int val) {
addAtIndex(0, val);
}
public void addAtTail(int val) {
addAtIndex(size, val);
}
public void addAtIndex(int index, int val) {
if (index > size) {
return;
}
index = Math.max(0, index);
size++;
ListNode pred = head;
for (int i = 0; i < index; i++) {
pred = pred.next;
}
ListNode toAdd = new ListNode(val);
toAdd.next = pred.next;
pred.next = toAdd;
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
size--;
ListNode pred = head;
for (int i = 0; i < index; i++) {
pred = pred.next;
}
pred.next = pred.next.next;
}
}
遇到的问题:细节问题很难注意到,可能还是思考问题不够熟练,没有形成肌肉记忆!
LeetCode 206.反转链表
思路:翻转链表核心思想就是将上一个节点的next指针指向前一个指针,所以需要利用双指针做调转,其中需要两个中间变量用来初始化和保存完成这一动作的中间值。定义pre节点为null,定义next节点为head,然后将next的下一个节点用中间值保存,next的下一个节点更改指向为pre节点,这样就完成了局部翻转。重复上述动作,直到next为null为止。
代码:
public class Day03_206 {
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode pre = null;
ListNode next = head;
while (next != null) {
ListNode node = next.next; // 保存原节点的下一个节点
next.next = pre; // 调换指针方向
pre = next; // 开始前移
next = node; // 开始前移
}
return pre;
}
}
遇到的问题:核心问题就是需要掌握双指针调转指针方向是如何实现的。定义两个中间变量的主要目的就是将next指针重新指向到pre节点上。