代码随想录算法训练营第3天
今日任务
● 链表理论基础 ● 203.移除链表元素 ● 707.设计链表 ● 206.反转链表
链接:https://docs.qq.com/doc/DUGdqYWNYeGhlaVR6 (opens in a new tab)
链表理论基础
复习一下C++和Java怎么声明、创建单链表
struct ListNode {
int val; // 节点上存储的元素
ListNode *next; // 指向下一个节点的指针
ListNode(int x) : val(x), next(NULL) {} // 节点的构造函数
};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;
}
}203.移除链表元素
设置一个虚拟头结点,这样原链表的所有节点就都可以按照统一的方式进行移除了。
自己想法
/**
* 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) {
ListNode dummy = new ListNode(-1, head);
ListNode cur = dummy.next;
ListNode pre = dummy;
while (cur != null) {
if (cur.val == val) {
// delete cur
pre.next = cur.next;
}
else {
pre = cur;
}
cur = cur.next;
}
return dummy.next;
}
}题解想法
无
困难
无
回顾
回顾虚拟头结点的思想。
707.设计链表
自己想法
class MyLinkedList {
class ListNode {
int val;
ListNode next;
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
ListNode head;
ListNode dummy;
int length;
public MyLinkedList() {
this.length = 0;
this.head = null;
this.dummy = new ListNode(-1, null);
}
public int get(int index) {
ListNode cur = this.head;
if (0 <= index && index <= this.length - 1) {
for (int i = 0; i < index; i++) {
cur = cur.next;
}
return cur.val;
}
else {
return -1;
}
}
public void addAtHead(int val) {
ListNode tmp;
if (this.length == 0) {
tmp = new ListNode(val, null);
}
else {
tmp = new ListNode(val, this.head);
}
this.head = tmp;
this.length ++;
}
public void addAtTail(int val) {
this.addAtIndex(this.length, val);
}
public void addAtIndex(int index, int val) {
this.dummy.next = this.head;
ListNode cur = this.dummy.next;
ListNode pre = this.dummy;
if (0 <= index && index <= this.length) {
for (int i = 0; i < index; i++) {
pre = cur;
cur = cur.next;
}
ListNode tmp = new ListNode(val, cur);
pre.next = tmp;
this.length ++;
this.head = this.dummy.next;
}
}
public void deleteAtIndex(int index) {
this.dummy.next = this.head;
ListNode cur = this.dummy.next;
ListNode pre = this.dummy;
if (0 <= index && index < this.length) {
for (int i = 0; i < index; i++) {
pre = cur;
cur = cur.next;
}
pre.next = cur.next;
this.length --;
this.head = this.dummy.next;
}
}
}题解想法
无
困难
无
回顾
无
206.反转链表
自己想法
相当于新建一个链表,每次往头部插入一个节点。
/**
* 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) {
ListNode reverse_head = new ListNode(head.val, null);
ListNode cur = head.next;
while (cur != null) {
ListNode tmp = new ListNode(cur.val, reverse_head);
reverse_head = tmp;
cur = cur.next;
}
return reverse_head;
}
else {
return null;
}
}
}题解想法
如果再定义一个新的链表,实现链表元素的反转,其实这是对内存空间的浪费。
其实只需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表。
一个 cur 一个 pre 指针就好。
困难
无
回顾
无