相关链接:
203.移除链表元素
这道题本身并不难,首先为了使操作方便,设置一个虚拟头节点,这样可以用相同的操作来移除所有的元素,不用对第一个元素进行单独的操作。然后从头开始遍历,遇到和val相同的值就直接移除就好。但我自己写的时候还是出现了问题,以下是有问题的代码。
ListNode* removeElements(ListNode* head, int val) {
ListNode* fakeHead = new ListNode(0);
fakeHead->next = head;
ListNode* p = fakeHead;
while (p->next!=nullptr) {
ListNode* q = p->next;
if (q->val == val) {
p->next = q->next;
delete q;
}
else {
p = p->next;
delete q;
}
}
head = fakeHead->next;//如果第一个被移除了,那么原来的head就会变
delete fakeHead;
return head;
}
提交这段代码会产生编译错误,原因是在else里面,p=p->next其实就是让p指向了q所指的节点,然后delete q删除了这个节点,释放了这个空间,然后下一个循环ListNode* q = p->next,可是p所指向的节点已经被释放了,又怎么会有p->next呢。只要把这个delete q删去,就能通过这道题,但是这样创建了很多没有用的指针,于是更改后的代码如下:
ListNode* removeElements(ListNode* head, int val) {
ListNode* fakeHead = new ListNode(0);
fakeHead->next = head;
ListNode* p = fakeHead;
while (p->next) {
if (p->next->val == val) {
ListNode* q = p->next;
p->next = q->next;
delete q;
}
else {
p = p->next;
}
}
head = fakeHead->next;//如果第一个被移除了,那么原来的head就会变
delete fakeHead;
return head;
}
707.设计链表
这道题其实就是自己创建一个链表,实现一些链表的常用操作,题目也不难,但是我还是没有一遍做对,我在写deleteAtIndex(int index)这个函数时出现了问题,以下是有问题的代码:
void deleteAtIndex(int index) {
ListNode* q = head;
int j = 0;
while (q->next && j < index) {
q = q->next;
++j;
}
ListNode* p = q->next;
q->next = p->next;
delete p;
}
这段代码之所以有问题,是因为没有考虑到index过大导致无效的情况,如果链表里只有3个元素,index却是100,那按照这段代码,创建的p所指向的内容为空,那么也就没有p->next了。修改后的代码如下:
void deleteAtIndex(int index) {
ListNode* q = head;
int j = 0;
while (q->next && j < index) {
q = q->next;
++j;
}
if (q->next) {
ListNode* p = q->next;
q->next = p->next;
delete p;
}
}
这道题目的完整代码如下:
class MyLinkedList {
public:
struct ListNode {
int val;
ListNode* next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode* next) : val(x), next(next) {}
};
MyLinkedList() {
head = new ListNode;
}
int get(int index) {
ListNode* p = head;
int j = 0;
int result = -1;
while (p->next && j < index) {
p = p->next;
++j;
}
if (p->next) {
result = p->next->val;
}
return result;
}
void addAtHead(int val) {
ListNode* p = new ListNode;
p->val = val;
p->next = head->next;
head->next = p;
}
void addAtTail(int val) {
ListNode* p = new ListNode;
p->val = val;
ListNode* q = head;
while (q->next) {
q = q->next;
}
q->next = p;
p->next = nullptr;
}
void addAtIndex(int index, int val) {
ListNode* p = new ListNode;
p->val = val;
ListNode* q = head;
int j = 0;
while (q->next && j < index) {
q = q->next;
++j;
}
if (j == index) {
p->next = q->next;
q->next = p;
}
else {
delete p;
}
}
void deleteAtIndex(int index) {
ListNode* q = head;
int j = 0;
while (q->next && j < index) {
q = q->next;
++j;
}
if (q->next) {
ListNode* p = q->next;
q->next = p->next;
delete p;
}
}
private:
ListNode* head;
};
206.反转链表
这道题目我自己做的时候并没有做出来,看完代码随想录给出的答案,才想到可以用双指针法。
示意图:
代码实现:
ListNode* reverseList(ListNode* head) {
ListNode* cur = head;
ListNode* pre = nullptr;
ListNode* temp = nullptr;
while (cur) {
temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}