Day 3
203. 移除链表元素
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if (head == nullptr) {
return head;
}
head->next = removeElements(head->next, val);
return head->val == val ? head->next : head;
}
};
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr) {
ListNode* next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
};
-
由于题目要求删除链表中所有val的值,故使用while循环。
-
在while循环中确保对当前作操作的节点不为NULL,否则对NULL进行操作编译器会报错。
-
C++中删除节点后要进行内存空间的释放,具体方法见代码。
-
删除时cur所在的位置是被删节点的前一位
java版:
class Solution {
public ListNode removeElements(ListNode head, int val) {
if (head == null) {
return head;
}
head.next = removeElements(head.next, val);
return head.val == val ? head.next : head;
}
}
206. 反转链表
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr) {
ListNode* next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
};
while中的循环条件:当cur指向原尾节点而pre指向尾节点的前一个节点时,还需要进行反转指向操作,操作完成后cur为“空节点”,pre指向NULL,此时不需要再进行操作,故while的循环条件为cur不为空节点。
在反转操作时,由于反转后cur指向pre,而cur->next节点此时与cur失去了联系,故需要定义一个临时节点temp始终指向cur->next节点,以便对cur节点进行移动到下一个节点的操作。
java版:
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
}
707. 设计链表
struct DLinkListNode {
int val;
DLinkListNode *prev, *next;
DLinkListNode(int _val) : val(_val), prev(nullptr), next(nullptr) {}
};
class MyLinkedList {
public:
MyLinkedList() {
this->size = 0;
this->head = new DLinkListNode(0);
this->tail = new DLinkListNode(0);
head->next = tail;
tail->prev = head;
}
int get(int index) {
if (index < 0 || index >= size) {
return -1;
}
DLinkListNode *curr;
if (index + 1 < size - index) {
curr = head;
for (int i = 0; i <= index; i++) {
curr = curr->next;
}
} else {
curr = tail;
for (int i = 0; i < size - index; i++) {
curr = curr->prev;
}
}
return curr->val;
}
void addAtHead(int val) {
addAtIndex(0, val);
}
void addAtTail(int val) {
addAtIndex(size, val);
}
void addAtIndex(int index, int val) {
if (index > size) {
return;
}
index = max(0, index);
DLinkListNode *pred, *succ;
if (index < size - index) {
pred = head;
for (int i = 0; i < index; i++) {
pred = pred->next;
}
succ = pred->next;
} else {
succ = tail;
for (int i = 0; i < size - index; i++) {
succ = succ->prev;
}
pred = succ->prev;
}
size++;
DLinkListNode *toAdd = new DLinkListNode(val);
toAdd->prev = pred;
toAdd->next = succ;
pred->next = toAdd;
succ->prev = toAdd;
}
void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
DLinkListNode *pred, *succ;
if (index < size - index) {
pred = head;
for (int i = 0; i < index; i++) {
pred = pred->next;
}
succ = pred->next->next;
} else {
succ = tail;
for (int i = 0; i < size - index - 1; i++) {
succ = succ->prev;
}
pred = succ->prev->prev;
}
size--;
DLinkListNode *p = pred->next;
pred->next = succ;
succ->prev = pred;
delete p;
}
private:
int size;
DLinkListNode *head;
DLinkListNode *tail;
};
- 操作链表时要注意循环终止条件
- 定义一个虚拟头链表会少很多头处理工作
获取第五个结点的值,即要让p到达第五个结点的位置。先让p=head->nextz作为p的起始位置用while循环不断让p往前,当index值到0的时候即代表以及到了该index的位置,循环停止。p->val就是要获取的值
在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点
即在head之后插入一个结点即可
将值为 val 的节点追加到链表的最后一个元素。
先遍历整个链表,让p到链表的最后一个元素,在p后面插入一个新元素即可
在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
如果索引 index 有效,则删除链表中的第 index 个节点
java版:
class MyLinkedList {
int size;
ListNode head;
public MyLinkedList() {
size = 0;
head = new ListNode(0);
}
public int get(int index) {
if (index < 0 || index >= size) {
return -1;
}
ListNode cur = head;
for (int i = 0; i <= index; i++) {
cur = cur.next;
}
return cur.val;
}
public void addAtHead(int val) {
addAtIndex(0, val);
}
public void addAtTail(int val) {
addAtIndex(size, val);
}
public void addAtIndex(int index, int val) {
if (index > size) {
return;
}
index = Math.max(0, index);
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--;
ListNode pred = head;
for (int i = 0; i < index; i++) {
pred = pred.next;
}
pred.next = pred.next.next;
}
}
class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}