leecode刷题笔记5.2打卡

链表

5.2打卡
题目链接:leecode203 移除链表元素

在刚开始一共想了两种写法,但是第一种写法真的是一个很低级的错误,分类讨论头节点情况时。删除头节点时的操作,因为在第一次操作的时候总是报错,
5。在这里插入图片描述

/**
 * 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) {
        ListNode* current = head;
        while(current){
            //分情况讨论,如果是头节点
           if(current->val == val){
                ListNode* tmp = current;
                current = tmp->next;
                delete tmp;
           }
           //如果不是头节点
           else if(current->next!=nullptr && current->next->val == val){
               ListNode *tmp = current->next;
               current->next = tmp->next;
               delete tmp;
           }
           else{
               current = current->next;
           }
        }
        return head;
    }
};

经过不断的测试才发现,错误的源头。这个报错告诉的我们是,我们在使用一个已经被delete的节点。确实是这样子的,我们仔细看,我们用current指向了头节点,所以当测试用例出现【7,7,7,7】,7的时候我们会把链表删干净,这时候如果返回头节点的话,这里的头节点已经被我们删除了!,所以只能返回current。所以以下写法是正确的不适用虚拟头节点的写法

/**
 * 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) {
        
        while(head!=nullptr && head->val == val){
            ListNode* tmp = head;
            head = head->next;
            delete tmp;
    
        }
        ListNode* current = head;

        while(current!=nullptr && current->next!=nullptr){
            if(current->next->val == val)
            {
            ListNode* tmp = current->next;
            current->next = tmp->next;
            delete tmp;
            }
            else
            {
                current = current->next;
            }
        }

        return head;
    }
};

下面介绍一种使用虚拟头节点的方法

/**
 * 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) {
        ListNode* dummyNode = new ListNode(0);
        dummyNode->next = head;
        ListNode* current = dummyNode;
        while(current->next!=nullptr){
           if(current->next->val == val){
           ListNode* tmp = current->next;
           current->next = tmp->next;
           delete tmp;
           }
           else current = current->next;
        }

        return dummyNode->next;
    }
};

第二种方法是比较推荐的方法,建立虚拟头节点,这样就不用考虑分情况的问题了。

题目链接:
leecode707 设计链表

这道题有几个需要注意的点就是,一定要设置size参数,因为很多测试用例,会删除一些根本不存在的数据。而且在添加,删减的时候也一定记得判断index和size之间的关系!代码如下

class MyLinkedList {
public:
    struct LinkedNode {
        int val;
        LinkedNode* next;
        LinkedNode(int val):val(val), next(nullptr){}
    };

    int size;
    LinkedNode* dummyNode;


    MyLinkedList() {
       dummyNode = new LinkedNode(0);
       size = 0;
    }

    int get(int index) {
        if(index > size-1 || index < 0) return -1;
        LinkedNode* current = dummyNode;
        while(index-->=0){
            current = current->next;
        }

        return current->val;

    }

    void addAtHead(int val) {
        LinkedNode* pN = new LinkedNode(val);
        pN->next = dummyNode->next;
        dummyNode->next = pN;
        size++;
    }

    void addAtTail(int val) {
        LinkedNode* pN = new LinkedNode(val);
        LinkedNode* cur = dummyNode;
        if(size == 0) dummyNode->next = pN;


        else{
            while(cur->next!=nullptr){
                cur = cur->next;
            }
            cur->next = pN;
        }
        
        size++;
    }

    void addAtIndex(int index, int val) {
        if(index <= size){
        //在第index之前添加,等于在index-1之后添加一个
        int new_index = index-1;
        LinkedNode* pN = new LinkedNode(val);
        LinkedNode* current = dummyNode;
        while(new_index-->=0){
            current = current->next;
        }

        pN->next = current->next;
        current->next = pN;
        size++;
        }
    }

    void deleteAtIndex(int index) {
        if(index < size){
         int new_index = index-1;
         LinkedNode* current = dummyNode;
         while(new_index-->=0){
             current = current->next;
         }
         LinkedNode* tmp = current->next;
         current->next = tmp->next;
         delete tmp;
         size--;
        }
    }
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值