day03 打卡203.移除链表元素 707.设计链表 206.反转链表
day03 打卡203.移除链表元素 707.设计链表 206.反转链表
203.移除链表元素
1.第一遍写的时候忘记了,先去看了代码随想录想起来了。我先写的是不需要虚拟节点的,比较容易忘记while先循环head肯定不等于val。
class Solution {
public ListNode removeElements(ListNode head, int val) {
while (head != null && head.val == val) head = head.next;
if (head == null) {
return head;
}
ListNode pre = head;
ListNode cur = pre.next;
while (cur != null) {
if (cur.val == val) {
// 删除操作
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return head;
}
}
2.使用虚拟节点的代码就比较清爽。
class Solution {
public ListNode removeElements(ListNode head, int val) {
if (head == null) {
return head;
}
// 虚拟头节点
ListNode dummy = new ListNode(-1, head);
ListNode pre = dummy;
ListNode cur = dummy.next;
while (cur != null) {
if (cur.val == val) {
// 删除操作
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return dummy.next;
}
}
707.设计链表
1.自己写的时候用的都是while循环,看来代码随想录之后感觉单反出现了index的传参,使用for循环更加明了清楚。通过index的for循环直接定位到需要删除or新增的当前节点或者前一节点。
class MyLinkedList {
// 元素个数
int size;
// 虚拟节点
ListNode dummy;
public MyLinkedList() {
size = 0;
dummy = new ListNode(-1, null);
}
public int get(int index) {
if (index < 0 || index >= size) {
return -1;
}
ListNode cur = dummy;
for (int i = 0 ; i<=index ; i++) {
cur = cur.next;
}
return cur.val;
}
public void addAtHead(int val) {
this.addAtIndex(0, val);
}
public void addAtTail(int val) {
this.addAtIndex(size, val);
}
public void addAtIndex(int index, int val) {
if (index < 0) {
index = 0;
}
if (index > size) {
return;
}
size++;
ListNode pre = dummy;
// 找到前驱节点
for (int i = 0 ; i<index ; i++) {
pre = pre.next;
}
ListNode add = new ListNode(val, pre.next);
pre.next = add;
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
size--;
if (index == 0) {
dummy = dummy.next;
return;
}
ListNode pre = dummy;
// 找到前驱节点
for (int i = 0 ; i<index ; i++) {
pre = pre.next;
}
pre.next = pre.next.next;
}
}
206.反转链表
1.第一遍写的时候,就思考循环往下的时候,如果反转过来,即cur.next=pre。但是还需要往下循环要记住cur之后的一串,所以先要用一个中间变量记住cur的后面。但是写出来出现了错误。错误代码如下:
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode temp = cur;
cur.next = pre;
pre = cur;
cur = temp.next;
}
return pre;
}
}
这是为什么错误呢?关键就是temp赋值了cur,但是cur.next在下面的操作中改变了,而我们想要的是之前的没反转的next。所以应该直接复制cur.next。很细节的错误。
正确代码如下:
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
}
2.写好之后,看代码随想录发现了还有递归的方法。强烈建议看了视频再去写,视频里说的很容易懂。递归直接看代码就容易不太清楚。
class Solution {
public ListNode reverseList(ListNode head) {
return reverseList(null, head);
}
public ListNode reverseList(ListNode preNode, ListNode curNode) {
if (curNode == null) return preNode;
ListNode temp = curNode.next;
// 反转的操作
curNode.next = preNode;
// 递归
// 此时传参的preNode向前移就是curNode, curNode就是没反转的下一个就是我们保存的temp
return reverseList(curNode, temp);
}
}

浙公网安备 33010602011771号