LeetCode 203移除链表元素 707设计链表 206反转链表 | 代码随想录25期训练营day3

链表涉及指针,很容易出现越界等编译报错问题!需要注意空指针和野指针等情况!

ListNode *p;
//p-next = head;错误!p指针没有分配存储空间,没有next,它的next不能指向某一对象
p = head;//正确,可以用其指向某一对象

LeetCode 203 移除链表元素 2023.10.27

  • 题目链接
  • 代码随想录讲解[链接]
    LeetCode 203移除链表元素 707设计链表 206反转链表 | 代码随想录25期训练营day3_第1张图片
  • 题意:输入某一链表及其头结点,删除链表内值为target的节点,并返回新链表的头结点
  • 方法:卡哥建议见到单链表一般都添加虚拟头节点,其后续节点为链表的头结点,在次基础上对后面节点能够统一处理;此题中判断当前节点的后续节点值是否等于target值,如果等于,则令当前节点的后一节点等于当前节点的后一节点的后一节点,相当于把当前节点的后一节点从链表中踢出然后删除
  • 一定小心!判断要遍历的节点是否为空,为空时访问value值会报错
  • 删除节点要知道该节点的前一节点
//以下是我没有看解析时自己的答案,没有使用虚拟头结点,在遍历时没有考虑头结点,最后单独考虑
ListNode* removeElements(ListNode* head, int val) {
    //创建遍历的临时指针节点,必须是指针,如果是节点不会产生变动,类似值传递!
    ListNode *temp = head;
    //判断,当前节点和下一节点不为空时遍历
    while (temp != NULL && temp->next != NULL)
    {
        //判断条件,当下一节点的value等于target时删除下一节点
    	if(temp->next->val == val)
        {
            //创建临时节点记录要被删除的节点,最后用于删除,节省空间
            ListNode *del = temp->next;
            //令当前节点的后一节点等于当前节点的后一节点的后一节点
            temp->next = temp->next->next;
            //删除后一节点占用的空间
            delete del;
        }
        //当后一节点的value不等于target时,用于遍历的临时节点向后遍历
   		 else
    		temp = temp->next;
    }
    //因为没有判断头节点value于target关系,所以最后单独考虑
    if(head != NULL && head->val == val)
    	head = head->next;  
    return head;
}

LeetCode 707 设计链表 2023.10.27

  • 题目链接
  • 代码随想录讲解[链接]
    LeetCode 203移除链表元素 707设计链表 206反转链表 | 代码随想录25期训练营day3_第2张图片
class MyLinkedList {
public:
    //在类中构造链表结构体供使用
    struct LinkNode
    {
        int val;
        LinkNode *next;
        //代码随想录+
        LinkNode(int val):val(val), next(nullptr){}
    };
    

    MyLinkedList() {
        //自己错误的地方 初始化不需要开辟节点
        //LinkNode *head = new LinkNode(0);
        //virhead->next = head;
        //在构造函数中开辟虚拟头节点,实际不使用该节点存储
        virhead = new LinkNode(0);
        size_ = 0;
    }
    
    int get(int index) {
        //判断条件,索引从0开始,所以索引不能小于0或大于size_-1
        if (index > (size_ - 1) || index < 0) {
            return -1;
        }
        //创建遍历节点指向第1个节点
        LinkNode *temp =  virhead->next;
        while (index--)
        {
            temp = temp->next;
        }
        return temp->val;
    }
    
    void addAtHead(int val) {
        //创建临时节点存放新数据
        LinkNode *newNode = new LinkNode(val);
        //temp->val = val;
        //先让临时节点的下一个节点指向第一个节点
        newNode->next = virhead->next;
        //临时节点成为第一个节点,链表元素个数加一
        virhead->next = newNode;
        size_++;
    }
    
    void addAtTail(int val) {
        //创建新节点存放新数据
        LinkNode *newNode = new LinkNode(val);
        //创建遍历节点用于判断是否为最后一个节点
        LinkNode *temp = virhead;
        while (temp->next != nullptr)
        {
            temp = temp->next;
        }
        temp->next = newNode;
        size_++;
    }
    
    void addAtIndex(int index, int val) {
        LinkNode *newNode = new LinkNode(val);
        //判断要插入位置是否合理
        if(index > size_)
            return;
        if(index < 0)
            index = 0;
        //错误 可能链表中没有实际节点
        //LinkNode *temp = virhead->next;
        LinkNode *temp = virhead;
        while (index--)
        {
            temp = temp->next;
        }
        newNode->next = temp->next;
        temp->next = newNode;
        size_++;
    }
    
    void deleteAtIndex(int index) {
        //判断索引是否合理
        if(index >= size_ || index < 0)
        {
            return;
        }
        LinkNode *temp = virhead; 
        while (index--)
        {
            temp = temp->next;
        }
        LinkNode *temp1 = temp->next;
        temp->next = temp->next->next;
        delete temp1;
        temp1 = nullptr;
        size_--;
    }
    int size_;
    //自己错误的地方,应该在构造函数中开辟虚拟头结点空间
    //LinkNode *virhead = new LinkNode(0);
    LinkNode *virhead;
};

LeetCode 206 反转链表 2023.10.27

  • 题目链接
  • 代码随想录讲解[链接]
    LeetCode 203移除链表元素 707设计链表 206反转链表 | 代码随想录25期训练营day3_第3张图片
  • 题意:输入一个链表,将链表中元素
  • 方法:将链表内每个节点的next指针指向该节点前面的节点
ListNode* reverseList(ListNode* head) {
    //创建用于存储临时节点的指针
    ListNode *temp;
    //创建一个空指针 用于记录、储存新链表的后面节点
    //同时初始化为空因为新链表最后一个节点为空
    ListNode *pre = NULL;
    //创建遍历使用的节点,最初为头节点
    ListNode *cur = head;
    //开始遍历,判断条件为当前遍历节点是否为空
    while(cur)
    {
        //用临时节点存储当前遍历的下一个节点,因为当前节点的next节点要变为左侧的节点
        temp = cur->next;
        //当前节点的next节点要变为左侧的节点(翻转)
        cur->next = pre;
        //新链表右侧的节点更新左移
        pre = cur;
        //遍历节点更新
        cur = temp;
    }
    //pre最后成为了旧链表的最后一个节点
    return pre;
}

你可能感兴趣的:(LeetCode刷题,代码随想录训练营,leetcode,链表,算法,数据结构)