首页 > 其他分享 >LeetCode 707 - 设计链表

LeetCode 707 - 设计链表

时间:2024-10-19 15:22:11浏览次数:8  
标签:index cur val 707 next 链表 节点 LeetCode

题目描述

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

单链表中的节点应该具备两个属性: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 的节点。

示例:

输入
["MyLinkedList", "addAtHead", "addAtTail", "addAtIndex", "get", "deleteAtIndex", "get"]
[[], [1], [3], [1, 2], [1], [1], [1]]
输出
[null, null, null, null, 2, null, 3]

解释
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addAtHead(1);
myLinkedList.addAtTail(3);
myLinkedList.addAtIndex(1, 2);    // 链表变为 1->2->3
myLinkedList.get(1);              // 返回 2
myLinkedList.deleteAtIndex(1);    // 现在,链表变为 1->3
myLinkedList.get(1);              // 返回 3
提示:
  • 0 <= index, val <= 1000
  • 请不要使用内置的 LinkedList 库。
  • 调用 getaddAtHeadaddAtTailaddAtIndex 和 deleteAtIndex 的次数不超过 2000 。

解题思路

 1.定义了一个名为LinkedNode的结构体,用于表示链表节点,结构体包含节点的值val和指向下一个节点的指针next。

 2.MyLinkedList类中使用了一个名为_dummyHead的虚拟头节点,这样可以避免处理头节点的特殊情况,并将链表的初始大小_size初始化为0。

 3.实现了get方法用于获取指定位置节点的值,addAtHead方法用于在链表头部插入节点,addAtTail方法用于在链表尾部插入节点,addAtIndex方法用于在指定位置插入节点,deleteAtIndex方法用于删除指定位置的节点。 

 4. 需要注意的是,在addAtTail方法中,通过遍历寻找尾部节点之后再进行插入操作,而在deleteAtIndex方法中,首先遍历找到要删除节点的前一个节点,然后进行节点删除操作。 这样的设计和实现满足了题目的要求,能够有效地对链表进行操作,并且使用了一个虚拟头节点来简化边界情况的处理。

算法实现

C++实现

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

    MyLinkedList() {
        _dummyHead=new LinkedNode(0); 
        _size=0;
    }
    
    int get(int index) {
        if(index<0||index>_size-1)
        {
            return -1;
        }
        LinkedNode*cur=_dummyHead->next;
        while(index--)
        {
            cur=cur->next;
        }
        return cur->val;
    }
    
    void addAtHead(int val) {
        LinkedNode*newNode=new LinkedNode(val);
        newNode->next=_dummyHead->next;
        _dummyHead->next=newNode;
        _size++;
    }
    
    void addAtTail(int val) {
        //int n=_size;
        LinkedNode*newNode=new LinkedNode(val);
        LinkedNode*cur=_dummyHead;
        while(cur->next!=NULL)
        {
            cur=cur->next;
        }
        newNode->next=cur->next;
        cur->next=newNode;
        _size++;
    }
    
    void addAtIndex(int index, int val) {
        if(index<0) index=0;
        if(index>_size) return;
        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) {
        if(index<0||index>_size-1)
        {
            return;
        }
        LinkedNode*cur=_dummyHead;
        while(index--)
        {
            cur=cur->next;
        }
        LinkedNode*tmp=cur->next;
        cur->next=cur->next->next;
        delete tmp;
        tmp=nullptr;
        _size--;
    }
    private:
        int _size;
        LinkedNode*_dummyHead;
};

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

复杂度分析

  • 时间复杂度:在get、addAtHead、addAtTail、addAtIndex和deleteAtIndex操作中,时间复杂度均为O(n),其中n为链表的长度。
  • 空间复杂度:空间复杂度也为O(n),主要是链表节点的空间占用。

总结

通过以上实现,我们设计并实现了一个简单的单链表MyLinkedList类,实现了初始化链表、获取指定位置节点值、在头部、尾部和指定位置插入节点,以及删除指定位置的节点等功能。这个实现是基于C++的,可以满足LeetCode707题目的要求。

希望这篇博客能对你有所帮助,如果有任何问题,欢迎和我一起讨论。

标签:index,cur,val,707,next,链表,节点,LeetCode
From: https://blog.csdn.net/J_z_Yang/article/details/143063575

相关文章

  • 链表实现两个链表LA和LB的交集、并集、大整数相加
    #include<iostream>usingnamespacestd;#include<math.h>#defineOK1#defineERROR0typedefintStatus; typedefstructLNode{    intdata;      structLNode*next;     }LNode,*LinkList;   intListLength(LinkListL)......
  • 02.数据结构介绍&顺序表、链表简述+对比
    目录一、什么是数据结构二、线性表三、顺序表四、链表五、顺序表和链表的区别一、什么是数据结构          数据结构是由“数据”和“结构”两个词组合而来。    数据:常见的数值1、2、3......,网页里的文字图片信息等都是数据。    ......
  • Leetcode 1129. 颜色交替的最短路径
    1.题目基本信息1.1.题目描述给定一个整数n,即有向图中的节点数,其中节点标记为0到n–1。图中的每条边为红色或者蓝色,并且可能存在自环或平行边。给定两个数组redEdges和blueEdges,其中:redEdges[i]=[a_i,b_i]表示图中存在一条从节点a_i到节点b_i的红色有向边,bl......
  • Leetcode 1135. 最低成本连通所有城市
    1.题目基本信息1.1.题目描述想象一下你是个城市基建规划者,地图上有n座城市,它们按以1到n的次序编号。给你整数n和一个数组conections,其中connections[i]=[x_i,y_i,cost_i]表示将城市x_i和城市y_i连接所要的cost_i(连接是双向的)。返回连接所有城市的最低成本,......
  • 【leetcode】 码住—两种办法解决力扣数学思想 “加一” 操作
     前言......
  • LeetCode题练习与总结:最大单词长度乘积--318
    一、题目描述给你一个字符串数组 words ,找出并返回 length(words[i])*length(words[j]) 的最大值,并且这两个单词不含有公共字母。如果不存在这样的两个单词,返回 0 。示例 1:输入:words=["abcw","baz","foo","bar","xtfn","abcdef"]输出:16解释:这两个单词为"abc......
  • LeetCode题练习与总结:灯泡开关--319
    一、题目描述初始时有 n 个灯泡处于关闭状态。第一轮,你将会打开所有灯泡。接下来的第二轮,你将会每两个灯泡关闭第二个。第三轮,你每三个灯泡就切换第三个灯泡的开关(即,打开变关闭,关闭变打开)。第 i 轮,你每 i 个灯泡就切换第 i 个灯泡的开关。直到第 n 轮,你只需要切换......
  • 代码随想录算法训练营第三天|203.移除链表元素,707.设计链表,206.反转链表
    1前言今日主要学习链表的基础leetcode203移除链表元素leetcode707设计链表leetcode206反转链表2链表的基础链表分为单链表和双链表,与字符串的区别就是链表是在一个里面存储了数据+下一个数据的内存地址链表中存储的内存空间是可以不连续的2.1链表的定义2.1.1......
  • LeetCode刷题日记之贪心算法(二)
    目录前言买卖股票的最佳时机II跳跃游戏跳跃游戏II总结前言在上一篇贪心算法的学习中,我们探讨了贪心算法的基本思路和逻辑框架。在这篇文章中,我将继续分享几道经典的LeetCode贪心算法题,并探讨其背后的解题思路和技巧。希望通过这些题目的实践,能加深我对贪心算法的理......
  • 83. 删除排序链表中的重复元素 线性法&快慢双指针
    83.删除排序链表中的重复元素给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。示例1:输入:head=[1,1,2]输出:[1,2]示例2:输入:head=[1,1,2,3,3]输出:[1,2,3]提示:链表中节点数目在范围 [0,300] 内-100<=......