单链表的设计(力扣刷题)

        你可以选择使用单链表或者双链表,设计并实现自己的链表。

        单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。

        如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。

实现 MyLinkedList 类:

        MyLinkedList() 初始化 MyLinkedList 对象。
        int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
        void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
        void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
        void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/design-linked-list

示例:

思路:

删除链表节点:

 添加链表节点:

 链表操作的两种方式:

  1. 直接使用原来的链表来进行操作。
  2. 设置一个虚拟头结点在进行操作。

采用虚拟头节点更加方便理解,思路也更加清晰,也不需要考虑头节点情况

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

    //将虚拟头节点作为头节点(生成头节点)
    MyLinkedList()
    {
       dummpyNode = new LinkedNode(0);
       size = 0;
    }
    
    //这点要把虚拟节点算进去,所以size-1
    int get(int index) 
    {
        if(index > (size - 1) || index < 0)
        {
            return -1;
        }

        LinkedNode* cur = dummpyNode->next;
        while(index--)
        {
            cur = cur->next;
        }

        return cur->val;
    }
    
    void addAtHead(int val) 
    {
        LinkedNode* newNode = new LinkedNode(val);
        newNode->next = dummpyNode->next;
        dummpyNode->next = newNode;
        size++;
    }
    
    void addAtTail(int val) 
    {
        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = dummpyNode;

        while(cur->next != NULL)
        {
            cur = cur->next;
        }

        cur->next = newNode;
        size++;
    }
    
    //添加头尾有特殊的函数实现功能,这点不需要实现所以是
    //index > size
    void addAtIndex(int index, int val) 
    {
        if(index > size || index < 0)
        {
            return;
        }

        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = dummpyNode;

        while(index--)
        {
            cur = cur->next;
        }

        newNode->next = cur->next;
        cur->next = newNode;
        size++;
    }
    
    //这点有>=是因为删除不涉及头尾
    void deleteAtIndex(int index) 
    {
      if(index >= size || index < 0)
      {
          return;
      }

      LinkedNode *cur = dummpyNode;
      while(index--)
      {
          cur = cur->next;
      }
      LinkedNode* tmp = cur->next;
      cur->next = cur->next->next;
      delete tmp;
      size--;
    }

private:
    LinkedNode *dummpyNode; //虚拟头节点
    int 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
    评论
好的,关于力扣刷C++常用操作,我可以给你一些常见的操作和技巧: 1. 使用 STL 容器和算法库:STL(Standard Template Library)是 C++ 标准库中的一个重要组成部分,包含了许多常用的容器和算法。在力扣刷中,使用 STL 可以大大提高代码的效率和可读性。例如,vector 可以用来存储动态数组,sort 可以用来排序等等。 2. 使用 auto 关键字:auto 关键字可以自动推导变量类型,可以减少代码量和提高可读性。例如,auto x = 1; 可以自动推导出 x 的类型为 int。 3. 使用 lambda 表达式:lambda 表达式是 C++11 中引入的一种匿名函数,可以方便地定义一些简的函数对象。在力扣刷中,使用 lambda 表达式可以简化代码,例如在 sort 函数中自定义比较函数。 4. 使用位运算:位运算是一种高效的运算方式,在力扣刷中经常会用到。例如,左移运算符 << 可以用来计算 2 的幂次方,右移运算符 >> 可以用来除以 2 等等。 5. 使用递归:递归是一种常见的算法思想,在力扣刷中也经常会用到。例如,二叉树的遍历、链表的反转等等。 6. 使用 STL 中的 priority_queue:priority_queue 是 STL 中的一个容器,可以用来实现堆。在力扣刷中,使用 priority_queue 可以方便地实现一些需要维护最大值或最小值的算法。 7. 使用 STL 中的 unordered_map:unordered_map 是 STL 中的一个容器,可以用来实现哈希表。在力扣刷中,使用 unordered_map 可以方便地实现一些需要快速查找和插入的算法。 8. 使用 STL 中的 string:string 是 STL 中的一个容器,可以用来存储字符串。在力扣刷中,使用 string 可以方便地处理字符串相关的问。 9. 注意边界条件:在力扣刷中,边界条件往往是解决问的关键。需要仔细分析目,考虑各种边界情况,避免出现错误。 10. 注意时间复杂度:在力扣刷中,时间复杂度往往是评判代码优劣的重要指标。需要仔细分析算法的时间复杂度,并尽可能优化代码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会飞的鱼-blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值