学算法,刷力扣,加油卷,进大厂!

题目描述

力扣题目链接

设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。

在链表类中实现这些功能:

  • get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
  • addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
  • addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
  • addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
  • deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。

示例:

MyLinkedList linkedList = new MyLinkedList();
linkedList.addAtHead(1);
linkedList.addAtTail(3);
linkedList.addAtIndex(1,2);   //链表变为1-> 2-> 3
linkedList.get(1);            //返回2
linkedList.deleteAtIndex(1);  //现在链表是1-> 3
linkedList.get(1);            //返回3

提示:

  • 所有val值都在 [1, 1000] 之内。
  • 操作次数将在 [1, 1000] 之内。
  • 请不要使用内置的 LinkedList 库。

涉及算法

道题目属于中等题型,涉及到数据结构中的链表。这道题目呢,要求我们去根据要求设计链表,而不是单单让我们根据题目要求使用链表这个数据结构。那我们就要根据链表一些特性进行设计:

  • 链表是由节点组成的,在链表的每个节点中,由两部分组成,即数据域(存放数据)和指针域(指向下一个节点的指针);
  • 链表不能像数组一样可以直接定位元素位置,因此它的查找比较慢;
  • 链表的删除和添加都是直接通过指针来添加的,因此不存在像数组一样的覆盖,这样就快了很多(如下图)

单链表

那么根据题目我们可以提炼出的关键点:

  • 可以使用单链表或者双链表
  • 单链表中的两个属性值,val 是当前节点的值,next 是指向下一个节点的指针/引用;双链表的话,在此基础上添加一个属性,prev 以指示链表中的上一个节点

解决这道题目呢,我们需要做的就是根据前面说到的链表的特性结合题目要求,设计链表类,然后实现指定的操作就可以了。(本文使用单链表实现,双链表后续补充)

题目解答

Java题解一

使用单链表

  • 使用单链表的话,需要给MyLinkedList 类中,添加一个虚拟的头结点,这样的话,方便题目要求的在链表的第一个位置添加;
  • 然后根据前面我们画的删除和添加的图发现,如果是删除元素,我们需要找到这个元素的前驱和后继节点;添加元素的话,需要根据其位置找到它的前驱节点和后继节点;
  • 为了方便链表的查找,我们给MyLinkedList 类中设置一个size属性,表示存储链表元素的个数。

根据以上分析,实现代码如下:

//定义单链表类
class ListNode{int val; //当前节点的值ListNode next; //指向下一个节点的指针ListNode(){ }ListNode(int val){this.val = val;}
}class MyLinkedList {//size 存储链表元素的个数int size;//虚拟头结点ListNode head;//初始化链表public MyLinkedList() {size = 0;head = new ListNode(0);}//获取第index节点的数值public int get(int index) {//如果index非法,返回-1if(index < 0|| index >= size ){return -1;}//定义移动的节点ListNode curNode = head;//包含一个虚拟节点,所以查找第index +1 个节点for(int i = 0; i <= index; i++){curNode = curNode.next;}return curNode.val;}//在链表最前面插入一个节点public void addAtHead(int val) {addAtIndex(0,val);}//在链表最后面插入一个节点public void addAtTail(int val) {addAtIndex(size,val);}public void addAtIndex(int index, int val) {//排除index大于链表长和小于0的情况if(index > size ){return;}if(index < 0){index = 0;}//定义前驱节点ListNode pre = head;//链表长度加一++size;//循环查找直到indexfor(int i = 0; i < index; i++){pre = pre.next; //往后查找}//定义插入的节点addListListNode addList = new ListNode(val);//将节点插入addList.next = pre.next;pre.next = addList;}public void deleteAtIndex(int index) {//排除index大于链表长和小于0的情况if(index >= size || index < 0){return;}//定义前驱节点ListNode pre = head;//链表长度减一size--;//循环查找直到indexfor(int i = 0; i < index; i++){pre = pre.next; //往后查找}//将节点删除pre.next = pre.next.next;}
}


复杂度分析

时间复杂度:

  • addAtHead: \O(1)
  • addAtInder,get,deleteAtIndex: O(k),其中 k 指的是元素的索引。
  • addAtTail:O(N),其中 N 指的是链表的元素个数。

空间复杂度:

  • 所有的操作都是 O(1)。

卷进大厂系列之LeetCode刷题笔记:设计链表(中等)相关推荐

  1. 卷进大厂系列之LeetCode刷题笔记:二分查找(简单)

    LeetCode刷题笔记:二分查找(简单) 学算法,刷力扣,加油卷,进大厂! 题目描述 涉及算法 题目解答 学算法,刷力扣,加油卷,进大厂! 题目描述 力扣题目链接 给定一个 n 个元素有序的(升序) ...

  2. 卷进大厂系列之LeetCode刷题笔记:反转链表(简单)

    学算法,刷力扣,加油卷,进大厂! 题目描述 力扣题目链接 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表. 示例 1: 输入:head = [1,2,3,4,5] 输出:[5,4,3 ...

  3. 卷进大厂系列之LeetCode刷题笔记:移除链表元素(简单)

    学算法,刷力扣,加油卷,进大厂! 题目描述 力扣题目链接 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回新的头节点 . 示 ...

  4. 卷进大厂系列之LeetCode刷题笔记:长度最小的子数组(中等)

    学算法,刷力扣,加油卷,进大厂! 题目描述 力扣题目链接 给定一个含有 n 个正整数的数组和一个正整数 target . 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl ...

  5. 卷进大厂系列之LeetCode刷题笔记:移除元素(简单)

    学算法,刷力扣,加油卷,进大厂! 题目描述 力扣题目链接 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度. 不要使用额外的数组空间, ...

  6. LeetCode刷题---707. 设计链表(双向链表-带头尾双结点)

    文章目录 一.编程题:707. 设计链表(双向链表-带头尾双结点) 1.题目描述 2.示例1: 3.提示: 二.解题思路 1.思路 2.复杂度分析: 3.算法图解(双向链表) 三.代码实现 三.单向链 ...

  7. LeetCode刷题笔记2——数组2

    LeetCode刷题笔记2--数组2 重塑数组 题目 在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原 ...

  8. 小何同学的leetcode刷题笔记 基础篇(01)整数反转

    小何同学的leetcode刷题笔记 基础篇(01)整数反转[07] *** [01]数学取余法*** 对数字进行数位操作时,常见的方法便是用取余的方法提取出各位数字,再进行操作 操作(1):对10取余 ...

  9. LeetCode刷题笔记汇总

    LeetCode刷题笔记汇总 第一次刷LeetCode写的一些笔记. 1.两数之和 3.无重复字符的最长子串 15.三数之和 18.四数之和 19.删除链表的倒数第 N 个结点 20.有效的括号 21 ...

最新文章

  1. Go借助PProf的一次性能优化
  2. MAC安装vmware虚拟机,安装window xp Ghost步骤
  3. 快刀斩“乱码”,你需要这些套路!
  4. java位运算(转)
  5. Docker上部署GitLab服务器
  6. 实现多个输入框的dialog
  7. 实体词典 情感词典_基于词典的情感分析——简单实例
  8. Windows句柄和指针的区别
  9. 知识图谱组队学习Task05——图数据库查询
  10. android 设备标识
  11. 实用软件工程(张海藩)复习笔记
  12. 十天学会单片机Day4串行口通信
  13. 英雄联盟一直连接服务器win10,手把手修复win10系统英雄联盟连接不上服务器的解决方法...
  14. 数据科学家VS大数据专家VS数据分析师:有什么不同?
  15. 多款AE字幕条模板动画
  16. 【PTA】【C语言】求闰年数
  17. 前一个问题的答案后续
  18. ctime(ctime头文件的作用)
  19. 动画《魁拔妖侠传》反思
  20. 匹兹堡计算机科学公司,UPitt的Computer Science「匹兹堡大学计算机科学系」

热门文章

  1. 【 FPGA 】序列检测器的Mealy状态机实现
  2. 使用【Sources】源文件视图和RTL编辑器
  3. .gitkeep是什么? .gitignore和.gitkeep之间的区别(译)
  4. 番茄时间管理和四象限工作法完美搭配造就职场神器
  5. 配置openStack使用spice
  6. System.Object 基类
  7. Mac虚拟机安装windows教程--Parallels 5
  8. ADO.NET 连接Access2007和Access2003
  9. 巧解SEP杀毒软件卸载需要密码才能完全卸载问题
  10. Windows中的路由表和默认网关