代码随想录算法训练营第三天 | 203.移除链表元素, 707.设计链表, 206.反转链表

过去学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;
    }
};
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值