过去学C语言的时候,我觉得最简单,学得最好的就是指针那一part,可能结构体还有些许疑惑,不过进入链表之后,光看理论觉得还是比较简单。此为前话,待会看题可能就不觉得自己过去的感觉对了。嘿
203.移除链表元素
这一题我一开始没有写上对头结点的判断,后来写指针指向空间是否为空实时,将p->next!=NULL之类的放在了&&之后,运行之后就报错啦
以下是修改过后自己的代码
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
// 之前少了一步判断头节点是否为目标值的操作
while (( head != NULL) &&(head->val == val)) { // 空指针判断是必须的,而且要在&&之前进行判断
ListNode* tmp = head;
head = head->next;
delete tmp;
}
ListNode* p = head;
while ( (p != NULL)&&(p->next != NULL) ) {
if (p->next->val == val)
p->next = p->next->next;
else
p = p->next;
}
return head;
}
};
然后卡尔给了一个新思路,为了统一链表操作,建立一个虚拟的头节点让它的next指向原本真正的头节点。
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
// new一个新的头节点
ListNode* dummyHead = new ListNode();
dummyHead->next = head;
ListNode* p = dummyHead;
while ((p != NULL) && (p->next != NULL)) {
ListNode* tmp; // 用以释放无用节点
if (p->next->val == val) {
tmp = p->next;
p->next = p->next->next;
delete tmp;
} else
p = p->next;
}
return dummyHead->next;
}
};
妙哉,目前第一题,觉得在找回过去的知识,不算难
707.设计链表
6-18来更新了,真是,学期末学校好多事。
首先去看了链表的定义和创建
但我个人的疑问还挺大的,而且力扣上过不去啊QAQ希望有大佬能解答我
服了, MyLinkedList() 之前多加};所以没过。检查这老半天
class MyLinkedList {
// 首先,我要明白一件事,MyLinkedList是一个类,所以不要为初始化中的
// MyLinkedList() 疑惑
public:
// 初始化链表
// 定义链表节点结构体
struct LinkedNode {
int val;
LinkedNode* next;
LinkedNode(int val) : val(val), next(nullptr) {}
};
// 初始化链表
MyLinkedList() {
_dummyHead = new LinkedNode(0);
// 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
// LinkedNode(0)是已经指向头节点了吗???
// 解答我自己,没有,这里还不涉及建立链表,只是初始化。链表的实体产生要到add方法。
_size = 0; // 链表长度
}
int get(int index) {
if (index > _size - 1 || index < 0)
return 0;
// 要确保没有胡乱搜索,否则指向不存在于链表的地址会出问题
LinkedNode* cur = _dummyHead->next; // 让cur指向头节点
while (index) {
cur = cur->next;
index--;
}
return cur->val;
}
void addAtHead(int val) {
LinkedNode* newNode = new LinkedNode(val);
/* LinkedNode *cur = nullptr;
cur->val = val;
我的赋值怎么看起来这么拙劣*/
newNode->next = _dummyHead->next;
_dummyHead->next = newNode;
_size++; // 记得
}
void addAtTail(int val) {
LinkedNode* newNode = new LinkedNode(val);
LinkedNode* cur = _dummyHead->next;
while (cur->next != nullptr)
cur = cur->next;
cur->next = newNode;
/*newNode->next = nullptr;
这边又是不必要的,因为节点构造中,next本身指向nullptr*/
_size++;
}
// 在第index个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
// 如果index 等于链表的长度,则说明是新插入的节点为链表的尾结点
// 如果index大于链表的长度,则返回空
// 如果index小于0,则在头部插入节点
void addAtIndex(int index, int val) {
/* LinkedNode *newNode = new LinkedNode(val);
LinkedNode *cur = _dummyHead->next;
while(index)
cur = cur->next;
newNode->next = cur->next;
cur->next = newNode;
_size++;*/
if (index > _size)
return;
if (index < 0)
index = 0;
LinkedNode* newNode = new LinkedNode(val);
LinkedNode* cur = _dummyHead;
while (index--) {
cur = cur->next;
}
newNode->next = cur->next;
cur->next = newNode;
_size++;
}
void deleteAtIndex(int index) {
// 删除第index个节点,如果index
// 大于等于链表的长度,直接return,注意index是从0开始的
if (index >= _size || index < 0) {
return;
}
LinkedNode* cur = _dummyHead; // cur指向的是index的前一个节点
while (index) {
cur = cur->next;
index--;
}
LinkedNode* tmp =
cur->next; // 此处让一个指针指向节点,后续删除,释放节点空间
cur->next = cur->next->next;
delete tmp;
tmp = nullptr; // 释放之后指针不能乱指
_size--;
}
private:
int _size;
LinkedNode* _dummyHead;
};
206.反转链表
单向链表的反转,倒也不难,自己写的大差不差,但是while的循环条件跳多了,返回值也返回了空。后来改了。
/**
* Definition for singly-linked list.
* 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) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* cur = head;
ListNode* p = nullptr;
ListNode* tmp=nullptr;
while (cur) {
p = cur->next;
cur->next = tmp;
tmp = cur;
cur = p;
}
return tmp;
}
};