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

7 篇文章 0 订阅
7 篇文章 0 订阅

LeetCode 203.移除链表元素

题目链接:203.移除链表元素

链表的定义:
// 单链表
struct ListNode {
    int val;  // 节点上存储的元素
    ListNode *next;  // 指向下一个节点的指针
    ListNode(int x) : val(x), next(NULL) {}  // 节点的构造函数
};
ListNode(int x) : val(x), next(NULL) {} 

此段代码是构造函数初始化列表,以一个冒号开始,接着是以逗号分隔数据成员列表,每个数据成员后面跟一个放在括号中的初始化式,初始化列表仅在构造函数中有效,不能用于其他函数。

等价于:
ListNode(int x) {
    val = x;
    next = nullptr;
}

注意:

如果不定义构造函数使用默认构造函数的话,在初始化的时候就不能直接给变量赋值。

思路:
1、设置一个虚拟头节点,方便对头节点进行操作
2、遍历往后找到符合条件的节点删除即可,记得释放空间
3、最后,将头节点换回原来的头节点,将虚拟头节点释放即可

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        //设置一个虚拟头节点,方便对链表所有节点进行统一操作
        ListNode* virtual_Head = new ListNode(0); // 设置一个虚拟头节点
        virtual_Head -> next = head;  // 虚拟头节点指向真实头节点
        //以下对链表所有元素都可以进行统一操作
        ListNode* cur = virtual_Head;
        while (cur -> next != nullptr) {     // 遍历终止条件
            if (cur -> next -> val == val) {
                //进行删除节点操作
                ListNode* tmp = cur -> next;
                cur -> next = cur -> next -> next;
                delete tmp;
            }
            //不符合往后遍历即可
            else{
                cur = cur -> next;
            }
        }
        //将头节点换成原来的头节点
        head = virtual_Head -> next;
        //删除原来的头节点
        delete virtual_Head;
        return head;
    }
};

在这里插入图片描述

LeetCode 707. 设计链表

题目链接:203.移除链表元素

思路:此题考查链表的基本构造,可以打好基础,充分理解好链表的基本知识,具体实现细节在注释里
** 注意:最后两个需求,根据index插入元素和删除元素的if有所不同**
1、根据index插入元素插入,if (index > _size || index < 0) { return; }
2、根据index删除元素,if (index >= _size || index < 0) { return; }

class MyLinkedList {
public:
    //定义链表结构体
    struct LinkedNode{
        int val; //节点对应的值
        LinkedNode *next; //指向当前节点的下一节点的指针
        //节点的构造函数
        LinkedNode(int val) : val(val),next(nullptr){}
    };
    //初始化链表
    MyLinkedList() {
        //创建一个虚拟头节点
        virtul_Head =  new LinkedNode(0);
        _size = 0;
    }
    
    //获取到第index个节点数值,如果index是非法数值直接返回-1, 注意index是从0开始的,第0个节点就是头结点
    int get(int index) {
        if (index > (_size - 1) || index < 0) {
            return -1;
        }
        LinkedNode* cur = virtul_Head -> next;
        //遍历终止条件
        while(index){
            cur = cur -> next;
            index --;
        }
        return cur -> val;
    }
    
    //创建一个新节点,将新节点指向头节点,虚拟头节点指向新节点
    void addAtHead(int val) {
        //创建这个新节点
        LinkedNode* new_Node = new LinkedNode(val);
        new_Node -> next = virtul_Head -> next;
        virtul_Head -> next = new_Node;
        _size ++;
    }
    
    //创建一个新节点和一个当前指针,首先遍历到最后,然后将最后一个节点指向这个新节点
    void addAtTail(int val) {
        LinkedNode* new_Node = new LinkedNode(val);
        LinkedNode* cur = virtul_Head;
        while (cur -> next !=nullptr) {
            cur = cur -> next;
        }
        cur -> next = new_Node;
        _size++;
    }
    
    //注意:这里的以下的while(index)
    void addAtIndex(int index, int val) {
        //这里的index < 0很巧妙,可以直接不用操作,因为后面怎么都会进行一次插入节点
        //注意这里的if()操作中index的细节,=_sized的操作也一起并到里面了
        if (index > _size || index < 0) {
            return;
        }
        LinkedNode* cur = virtul_Head;
        while (index) {
            cur = cur -> next;
            index --;
        }
        //创建新节点,进行插入
        LinkedNode* new_Node =  new LinkedNode(val);
        new_Node -> next = cur -> next;
        cur -> next = new_Node;
        _size ++;
    }
    
    void deleteAtIndex(int index) {
        if (index >= _size || index < 0) {
            return;
        }
        LinkedNode* cur = virtul_Head;
        while (index) {
            cur = cur -> next;
            index --;
        }
        //进行删除节点操作
        //创建一个临时节点,指向要删除的节点
        LinkedNode* tmp = cur -> next;
        cur -> next = cur -> next -> next;
        delete tmp;
        _size --;
    }

    //打印链表
    void printList(){
        //遍历打印即可
        LinkedNode* cur = virtul_Head;
        while (_size) {
            cout << cur -> next -> val << " ";
            cur = cur -> next;
            _size --;
        }
        cout << endl;
    }
private:   
    int _size;
    LinkedNode* virtul_Head;
};

/**
 * 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);
 */

LeetCode 206.反转链表

题目链接:206.反转链表

思路:此题较为简单,后续有时间再看递归解法吧
1、使用双指针进行遍历,不停的让后面的节点指向前面的节点即可

/**
 * 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* pre = nullptr;
        ListNode* tmp;
        while (cur) {
            tmp = cur -> next;
            cur -> next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值