Day3 力扣链表 :203.移除链表元素 | 707.设计链表 | 206.反转链表
203.移除链表元素:
建议:本题最关键是要理解 虚拟头结点的使用技巧,这个对链表题目很重要。
题目链接:https://leetcode.cn/problems/remove-linked-list-elements/
文章讲解:https://programmercarl.com/0203.移除链表元素.html#算法公开课
视频讲解: https://b23.tv/srhzDRG
第一印象:
第二次做这道题了,一拿到就会了,直接ac一遍通过了牛逼!考点是用虚拟头节点,这样对所有节点的操作就统一了。
看完题解的思路:
思路和我一致,我是天才。但是要学的是c++中需要手动释放这个被删除节点的内存,但是java和python有内存回收机制,就不用释放这个节点了。
实现过程中的困难:
没有困难啊,无敌了。return 头结点的时候,别忘了 return dummyNode->next;
这才是新的头结点,因为head节点可能被删掉。
感悟:
学习知识,如果使用C,C++编程语言的话,不要忘了还要从内存中删除,使用java ,python的话就不用手动管理内存。java这个机制我还没仔细学过,先记着吧。
最后附上代码:
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode dummyNode = new ListNode();
ListNode pre = new ListNode();
ListNode cur = new ListNode();
dummyNode.next = head;
cur = head;
pre = dummyNode;
while (cur != null) {
if (cur.val == val) {
cur = cur.next;
pre.next = cur;
} else {
cur = cur.next;
pre = pre.next;
}
}
return dummyNode.next;
}
}
707.设计链表
建议: 这是一道考察 链表综合操作的题目,不算容易,可以练一练 使用虚拟头结点
题目链接/文章讲解/视频讲解:https://programmercarl.com/0707.%E8%AE%BE%E8%AE%A1%E9%93%BE%E8%A1%A8.html
第一印象:
之前做过,而且这道题不难理解,就是对一些循环的终止条件做好判断,我一顿写还是写出来了,但是debug了挺久。
看完题解的思路:
对于循环终止条件的判断我都写对了。
题解中在头和尾插入元素使用addAtIndex()进行操作,这是我没想到的,太合理了。再就是,链表插入元素,只需要找到插入位置前面的节点cur。而删除元素才需要 pre 和 cur。
实现过程中的困难:
if (index < 0 || index > this.length) {
return;
}
while (i++ <= index) {
cur = cur.next;
pre = pre.next;
}
if 和 while 中的判断条件是我这道题最纠结的地方,我是一个一个举例子去判断是否取等。这道题想一次通过感觉还是很难的,但是思想并不难。
感悟:
希望下次能一次写对吧,这次已经比上次写一半放弃好多了捏 : )
最后附上代码,我贴我自己写的不好的,好的就去代码随想录里学习吧。:
class LinkNode {
int val;
LinkNode next;
public LinkNode () {
}
public LinkNode (int val) {
this.val = val;
}
public LinkNode (int val, LinkNode node) {
this.val = val;
this.next = node;
}
}
//链表定义
class LinkNode {
int val;
LinkNode next;
public LinkNode () {
}
public LinkNode (int val) {
this.val = val;
}
public LinkNode (int val, LinkNode node) {
this.val = val;
this.next = node;
}
}
class MyLinkedList {
LinkNode dummyHead;
int length;
public MyLinkedList() {
this.dummyHead = new LinkNode();
this.length = 0;
}
public int get(int index) {
if (index < 0) { return -1; }
LinkNode cur = this.dummyHead;
int i = 0;
while (i++ <= index && cur != null) {
cur = cur.next;
}
if (cur != null) { return cur.val; }
return -1;
}
public void addAtHead(int val) {
LinkNode newNode = new LinkNode(val, this.dummyHead.next);
this.dummyHead.next = newNode;
this.length++;
}
public void addAtTail(int val) {
LinkNode lastNode = new LinkNode();
LinkNode newNode = new LinkNode(val);
lastNode = this.dummyHead;
while (lastNode.next != null) {
lastNode = lastNode.next;
}
lastNode.next = newNode;
this.length++;
}
public void addAtIndex(int index, int val) {
if (index < 0 || index > this.length) {
return;
}
LinkNode newNode = new LinkNode(val);
LinkNode cur = this.dummyHead;
LinkNode pre = new LinkNode();
pre.next = cur;
int i = 0;
while (i++ <= index) {
cur = cur.next;
pre = pre.next;
}
pre.next = newNode;
newNode.next = cur;
this.length++;
}
public void deleteAtIndex(int index) {
if (index < 0 || index + 1 > this.length) {
return;
}
LinkNode cur = this.dummyHead;
LinkNode pre = new LinkNode();
pre.next = cur;
int i = 0;
while (i++ <= index) {
cur = cur.next;
pre = pre.next;
}
cur = cur.next;
pre.next = cur;
this.length--;
}
public void print() {
LinkNode cur = this.dummyHead.next;
while (cur != null) {
System.out.println(cur.val);
cur = cur.next;
}
}
}
206.反转链表
建议先看我的视频讲解,视频讲解中对 反转链表需要注意的点讲的很清晰了,看完之后大家的疑惑基本都解决了。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0206.%E7%BF%BB%E8%BD%AC%E9%93%BE%E8%A1%A8.html
第一印象:
这道题其实也不难,但是太晚了,不想熬夜了,仔细做做能成,直接看题解了。
看完题解的思路:
和我想的一样,需要三个节点操作。双指针的方法其实不难,但是那个递归感觉好难,但我好困,等以后突破递归的时候一起总结吧,先做个标记好了。
实现中的困难:
直接就做出来了,代码真不难,就是递归还不会哈哈哈哈。
感悟:
递归这个东西一直没弄明白,这道题的听卡哥讲感觉好像还挺有道理,我不知道递归函数中最后那个传参是为什么,明天睡醒再说吧,今天真的好累,要去看圣母了。
最后附上我自己写的双指针的方法吧:
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;
}
}