今天学习了链表基础知识;令我记忆深刻的是,在定义节点和指针的时候,我会分不清到底定义的是指针还是节点,后来终于明白了
// 单链表 struct ListNode { int val; // 节点上存储的元素 ListNode *next; // 指向下一个节点的指针 ListNode(int x) : val(x), next(NULL) {} // 节点的构造函数 };
ListNode* p 创建一个指针;
ListNode* p = new ListNode(); 创建一个节点;
ListNode* p = head 创建一个指针,因为没有构造方法,所以是个指针,同时p和head指向同一个节点,都指向头节点;
题目链接:203.移除链表元素
题目链接/文章讲解/视频讲解::代码随想录
第一想法:
移除链表,首先要找到移除的节点,这个时候需要遍历链表,同时我们要明白,删除结点的时候,我们需要找到被删除节点的前驱;这个时候我们就会遇到一种情况,头节点没有前驱,怎么办呢,这时候我们,需要对头节点单独处理一下是我的代码;
/**
* 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* removeElements(ListNode* head, int val) {
if(head == NULL)
return head;
//判断头节点是不是,是的话删除头节点
while(head != NULL && head->val == val) {
ListNode *tmp = head;
head = head->next;
delete tmp;
}
//判断不是头结点的节点;
if(head == NULL)
return head;
ListNode *pre = head;
ListNode *cur = head->next;
while(cur != NULL) {
if(cur->val == val) {
pre->next = cur->next;
ListNode *tmp2 = cur;
cur = cur->next;
delete tmp2;
}
else {
pre = cur;
cur = cur->next;
}
}
return head;
}
};
//时间复杂度: O(n)
//空间复杂度: O(1)
看完代码随想录之后的想法:
原来还有一种增加虚拟头节点的方法;感觉很妙,从卡哥这里学到了许多;
以下是卡哥代码:
//时间复杂度: O(n)
//空间复杂度: O(1)
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点
dummyHead->next = head; // 将虚拟头结点指向head,这样方面后面做删除操作
ListNode* cur = dummyHead;
while (cur->next != NULL) {
if(cur->next->val == val) {
ListNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
} else {
cur = cur->next;
}
}
head = dummyHead->next;
delete dummyHead;
return head;
}
};
自己实现过程中遇到的困难 :
在返回结果是我们注意不能直接返回头节点,因为head还是原来的链表的开头,所以我们要返回虚拟头节点的下一个;
题目: 707.设计链表
题目链接/文章讲解/视频讲解:代码随想录
第一想法:
好吧,不会;
看完代码随想录之后的想法:需要注意index表达的含义,index从0开始;
自己实现过程中遇到的困难 :创建节点时,不带构造方法的就是节点;
题目链接:206.反转链表
题目链接/文章讲解/视频讲解:代码随想录
自己实现过程中遇到的困难 :看到这道题有思路,就是创建两个指针一个在前,一个在后,更改后指针的指向的节点就好,然后两个指针后移,不过我们要有一个tmp保存一下后节点指向的值,因为会改变,影响后指针如何移动;
总结:
ListNode *p = head;是创建了一个指针,因为没有构造方法,所以不可能是创建节点,也就是说,创建节点,需要构造方法,因此p和head 都指向了头节点;