代码随想录算法训练营第3天 | 203.移除链表元素、707.设计链表、206.反转链表
203.移除链表元素
题目:203.移除链表元素
文档讲解:代码随想录-203.移除链表元素
视频讲解:哔哩哔哩-203.移除链表元素
状态/时间:写出来了/十五分钟
思路:
在头结点前面加一个虚拟头结点dummy_head,然后让虚拟头结点指向真正的头结点。
再遍历一下链表,有相等的值,遇到相等的时候,直接让虚拟头结点的下一个指针指向下下个。
最后返回的dummy_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 head;
ListNode dummy_head = new ListNode();
dummy_head.next = head;
ListNode cur = dummy_head;
while (cur.next != null) {
if (cur.next.val == val) {
cur.next = cur.next.next;
}else{
cur = cur.next;
}
}
// 这里返回dummy_head.next是因为下一个才是真正的头结点
return dummy_head.next;
}
}
注意:
不要return head,可能head已经被我们删了,要return 的是 dummy head->next
707.设计链表
题目:707.设计链表
文档讲解:代码随想录-707.设计链表
视频讲解:哔哩哔哩-707.设计链表
状态/时间:没写出来/四十分钟
思路:
这里就是设计一个链表,这里设计的是单链表。
先把插入指定位置元素的先写出来,后面的就好写了。
代码:
class ListNode{
int val;
ListNode next;
public ListNode() {
}
public ListNode(int val) {
this.val = val;
}
}
class MyLinkedList {
// 单链表的长度
int size;
// 虚拟头结点
ListNode head;
public MyLinkedList() {
size = 0;
head = new ListNode(0);
}
public int get(int index) {
//如果index非法,返回-1
if (index < 0 || index >= size) {
return -1;
}
ListNode cur = head;
//包含一个虚拟头节点,所以查找第 index+1 个节点
for (int i = 0; i <= index; i++) {
cur = cur.next;
}
return cur.val;
}
public void addAtHead(int val) {
// ListNode node = new ListNode(val);
// node.next = dummy_head.next;
// dummy_head.next = node;
// size++;
addAtIndex(0,val);
}
public void addAtTail(int val) {
// ListNode node = new ListNode(val);
// ListNode cur = dummy_head;
// while (cur.next != null) {
// cur = cur.next;
// }
// cur.next = node;
addAtIndex(size,val);
}
public void addAtIndex(int index, int val) {
if (index > size) {
return;
}
if (index < 0) {
index = 0;
}
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不能在后面--
size--;
if (index == 0) {
head = head.next;
return;
}
ListNode pred = head;
for (int i = 0; i < index ; i++) {
pred = pred.next;
}
pred.next = pred.next.next;
}
}
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList obj = new MyLinkedList();
* int param_1 = obj.get(index);
* obj.addAtHead(val);
* obj.addAtTail(val);
* obj.addAtIndex(index,val);
* obj.deleteAtIndex(index);
*/
注意:
1.删除那部分的size–,要在判断之后就–
2.头插尾差直接调用指定位置插入的方法就行了
206.反转链表
题目:206.反转链表
文档讲解:代码随想录-206.反转链表
视频讲解:哔哩哔哩-206.反转链表
状态/时间:没写出来/三十分钟
思路:
定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。
然后就要反转了,接下来不断循环移动指针。最后返回pre指针。
代码:
/**
* 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 reverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode cur = head;
ListNode pre = null;
while (cur != null) {
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
}
注意:
1.要注意循环终止条件
2.先把cur赋值给pre