代码随想录算法训练营第三天| 链表理论基础, 203.移除链表元素,707.设计链表,206.反转链表
链表理论基础
建议:了解一下链接基础,以及链表和数组的区别 文章链接:
203.移除链表元素
建议: 本题最关键是要理解 虚拟头结点的使用技巧,这个对链表题目很重要。
题目链接/文章讲解/视频讲解
看到题目的第一想法:
由于链表的头结点可能就是我们需要删除的节点,因此设置一个虚拟头节点,对我来说更好处理。设置一个虚拟头节点preHead,当前节点的前一个节点pre,当前节点cur,如果cur的值等于val则pre.next = cur.next,cur = cur.next;由于java有垃圾处理机制,因此不需要像c++一样手动删除节点。如果cur的值与val不相等,则pre和cur指针往下走一位。
package com.second.day3;
public class ListNode {
int val;
ListNode next;
public ListNode() {
}
public ListNode(int val) {
this.val = val;
}
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
package com.second.day3;
public class RemoveElements_203 {
public ListNode removeElements(ListNode head, int val) {
//设置一个虚拟头结点
ListNode preHead = new ListNode(-1);
preHead.next = head;
ListNode pre = preHead; //当前节点的前一个节点
ListNode cur = head; //当前节点
while(cur != null) {
if(cur.val == val) {
pre.next = cur.next;
cur = cur.next;
}
else {
pre = cur;
cur = cur.next;
}
}
return preHead.next;
}
}
看完代码随想录之后的想法:
如果不设置虚拟头节点,那么头结点的删除需要单独处理,如何处理呢?就是把头结点向后移动一位即可,接下来的操作与设置虚拟头结点的操作一样。
自己实现过程中遇到哪些困难:
没有遇到问题。直接AC了,第一次写的小伙伴们可能不能一下写出来,但一直坚持下去就会有意想不到的结果。
707. 设计链表
建议: 这是一道考察 链表综合操作的题目,不算容易,可以练一练 使用虚拟头结点
题目链接/文章讲解/视频讲解:
看到题目的第一想法:
看到这个题目后,我记得我第一次写的时候,完全看不懂题目。今天做的时候也是看不太懂,果然写代码的时候还是看了点卡哥代码。
我没看懂题目有:
1.该链表设计是基于单链表或者是双链表的。
2.该链表节点的第一个节点是0号节点。
经过自己的努力在不看卡哥主要代码下AC了
package com.second.day3;
public class MyLinkedList {
int size;
ListNode head;
public MyLinkedList() {
size = 0;
head = new ListNode(0);
}
public int get(int index) {
if(index >= size || index < 0)
return -1;
ListNode curNode = head.next;
for(int i = 0; i < index; i++) {
curNode = curNode.next;
}
return curNode.val;
}
public void addAtHead(int val) {
addAtIndex(0, val);
}
public void addAtTail(int val) {
addAtIndex(size, val);
}
public void addAtIndex(int index, int val) {
//如果 index 大于链表长度,则不会插入节点。
if(index > size)
return;
ListNode newNode = new ListNode(val);
ListNode preNode = head;
ListNode curNode = head.next;
//如果index小于0,则在头部插入节点。
if(index < 0) {
preNode.next = newNode;
newNode.next = curNode;
}
//如果 index 等于链表的长度,则该节点将附加到链表的末尾。
if(index == size) {
for(int i = 0; i < size; i++) {
preNode = preNode.next;
}
preNode.next = newNode;
}
//如果 index 在[0, size - 1]
if(index >= 0 && index < size) {
for(int i = 0; i < index; i++) {
preNode = curNode;
curNode = curNode.next;
}
preNode.next = newNode;
newNode.next = curNode;
}
size += 1;
}
public void deleteAtIndex(int index) {
if(index < 0 || index >= size)
return;
ListNode preNode = head;
ListNode curNode = head.next;
for(int i = 0; i < index; i++) {
preNode = curNode;
curNode = curNode.next;
}
preNode.next = curNode.next;
size -= 1;
}
public static void main(String[] args) {
MyLinkedList linkedList = new MyLinkedList();
linkedList.addAtHead(1);
linkedList.addAtTail(3);
linkedList.addAtIndex(1,2); //链表变为1-> 2-> 3
linkedList.get(1); //返回2
linkedList.deleteAtIndex(1); //现在链表是1-> 3
linkedList.get(1);
}
}
看完代码随想录之后的想法:
我觉得我和卡哥代码差不多,但其双链表的实现还没弄明白,今天需要找个时间弄明白。
自己实现过程中遇到哪些困难:
不知道如何初始化链表,其次初始化链表的head其实是虚拟头结点。
206.反转链表
建议先看我的视频讲解,视频讲解中对 反转链表需要注意的点讲的很清晰了,看完之后大家的疑惑基本都解决了。
题目链接/文章讲解/视频讲解:
看到题目的第一想法:
pre:指向当前节点的前一个节点,初始值为null
cur:指向当前节点
temp:遍历过程中暂时保存cur的下一个节点
最好写代码之前手动画下图,会让自己的思路变得清晰。
package com.second.day3;
public class ReverseList_206 {
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;
}
}
看完代码随想录之后的想法:
尝试了一下递归法,对递归法有了点了解
自己实现过程中遇到哪些困难:
没有困难,哈哈哈哈
今日收获,记录一下自己的学习时长:
今天写了四个题:
203.移除链表元素,707.设计链表,206.反转链表,1005. K 次取反后最大化的数组和
代码:1.5h
博客:1h
不积跬步无以至千里,不积小流无以成江海。继续努力。