题目:203.移除链表
文章链接:代码随想录
视频链接:LeetCode: 203.移除链表元素
题目链接:力扣题目链接
解法1:删除头节点
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
// 判断前面是不是有目标值
while(head != NULL && head->val == val)
{
head = head->next;
}
if(head == NULL){
return head;
}
// 如果链表开头有一串目标值的节点作为前缀的话,就可以直接将head跳过这些节点来删除,
//这是这个while的作用,如果说整个链表的节点都是目标值,那head==null就直接通过if返回了。
//如果交换顺序,在整个链表的节点都是目标值情况下,经过while循环,head会为null,
//但是没法通过if退出,然后后面又访问了head.next,就发生空指针引用了
// 删除非头节点
ListNode* pre = head;
ListNode* cur = head->next ;
while(cur!= NULL) // 当前指针不为空,以及下一个指针也不为空则循环
{
if(cur->val == val)
{
pre->next = cur->next;
}
else{
pre = cur ;
}
cur = cur->next;
}
return head;
}
};
解法2:创建虚拟头节点
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
// 创建虚拟头节点
ListNode *demmpHead = new ListNode(0); // 创建新的列表头
demmpHead->next = head; //将虚拟头指向head
ListNode *cur = demmpHead;
while(cur->next != NULL ) // cur可以为NULL,当cur为NULL时,cur->next也为NULL
{
if(cur->next->val == val )
{
ListNode *temp = cur->next;
cur->next = cur->next->next;
delete temp; // 释放内存
}
else{
cur = cur->next; // 往下走
}
}
head = demmpHead->next;
delete demmpHead;
return head;
}
}
};
题目:707.设计链表
文章链接:代码随想录
视频链接:LeetCode: 707.设计链表
题目链接:力扣题目链接
解法1:
// 定义一个类
class MyLinkedList {
public:
// 定义链表节点结构体
struct LinkedList {
int val;
LinkedList* next;
LinkedList(int val) :val(val), next(nullptr) {}
};
private:
int _size; // 在addAtHead中会进行size++的操作,所以定义一个全局数值
LinkedList* _dummyHead;
public:
// 初始话链表 无参构造函数
MyLinkedList() {
_dummyHead = new LinkedList(0); // 在前面加_ 是为了区别类内全局值
_size = 0;
}
int get(int index) {
if (index < 0 || index >= _size) // 小于0肯定是不对的,eg size = 0,里面没有数,index=0表示访问第一个数,但里面是没数的,所以返回-1
return -1;
LinkedList* cur = _dummyHead->next;
while (index--) // 0 是可以进while里的
{
cur = cur->next; //循环下一个元素
}
return cur->val;
}
// 在链表最前面插入一个节点,插入完成后,新插入的节点为链表的新的头结点
void addAtHead(int val) {
LinkedList* newnode = new LinkedList(val);
// 更换循序很关键
newnode->next = _dummyHead->next;
_dummyHead->next = newnode;
_size++;
}
void addAtTail(int val) {
LinkedList* newnode = new LinkedList(val);
LinkedList* cur = _dummyHead;
// 循环到链表尾
while (cur->next != NULL)
{
cur = cur->next;
}
cur->next = newnode; // 把原先的末尾节点赋值给新的节点
_size++; // 计数增加
}
void addAtIndex(int index, int val) {
// 根据添加的位置分类讨论
if (index>_size || index < 0){
return;
}
else if (index==_size) { //在末尾进行添加
addAtTail(val);
return;
}
else if (index==0){ //在头部添加
addAtHead(val);
return;
}
LinkedList* newnode =new LinkedList(val); //新建一个节点
LinkedList* cur = _dummyHead;
while (index--) // 定位到插入的前一位
{
cur = cur->next;
}
newnode->next = cur->next;
cur->next = newnode;
_size++;
}
void deleteAtIndex(int index) {
// 首先还是判断index还不是合规
if (index < 0 || index >= _size)
return ;
LinkedList* cur = _dummyHead;
while (index--) // 定位到插入的前一位 实在理不顺就换一个自己懂的
{
cur = cur->next;
}
LinkedList* temp = cur->next;
cur->next = temp->next;
delete temp;
//delete命令指示释放了tmp指针原本所指的那部分内存,
//被delete后的指针tmp的值(地址)并非就是NULL,而是随机值。也就是被delete后,
//如果不再加上一句tmp=nullptr,tmp会成为乱指的野指针
//如果之后的程序不小心使用了tmp,会指向难以预想的内存空间
temp = NULL;
_size--;
}
};
题目:206.反转指针
文章链接:代码随想录
视频链接:LeetCode: 206.反转链表
题目链接:力扣题目链接
解法1:
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* temp;
ListNode* cur = head;
ListNode* pre = NULL; //作为尾部进行连接
while(cur) // 当cur为空指针的时候,循环结束
{
// 暂存
temp = cur->next;
// 翻转 顺序不能相反
cur->next = pre;
// 更新
pre = cur ;
cur = temp;
}
return pre; // 当cur为空指针的时候,pre就是head了
}
};