leetcode设计链表,非常工整的实现你值得拥有

设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性: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 库。

 

 

链表:一个包含零个或多个元素的数据结构。每个元素都包含一个值和到另一个元素的链接。根据链接数的不同,可以分为单链表,双链表和多重链表。

单链表是最简单的一种,它提供了在常数时间内的 addAtHead 操作和在线性时间内的 addAtTail 的操作。双链表是最常用的一种,因为它提供了在常数时间内的 addAtHead 和 addAtTail 操作,并且优化的插入和删除。

双链表在 Java 中的实现为 LinkedList,在 Python 中为 list。这些结构都比较常用,有两个要点:

哨兵节点:
哨兵节点在树和链表中被广泛用作伪头、伪尾等,通常不保存任何数据。

我们将使用伪头来简化我们简化插入和删除。在接下来的两种方法中应用此方法。

双链表的双向搜索:我们可以从头部或尾部进行搜索。
单链表
让我们从最简单的链表开始。

class MyLinkedList {int size;ListNode head;  // sentinel node as pseudo-headpublic MyLinkedList() {size = 0;head = new ListNode(0);}
}


哨兵节点被用作伪头始终存在,这样结构中永远不为空,它将至少包含一个伪头。MyLinkedList 中所有节点均包含:值 + 链接到下一个元素的指针。

public class ListNode {int val;ListNode next;ListNode(int x) { val = x; }
}


addAtIndex,addAtHead 和 addAtTail:
我们首先讨论 addAtIndex,因为伪头的关系 addAtHead 和 addAtTail 可以使用 addAtIndex 来完成。

这个想法很简单:

找到要插入位置节点的前驱节点。如果要在头部插入,则它的前驱节点就是伪头。如果要在尾部插入节点,则前驱节点就是尾节点。
通过改变 next 来插入节点。

toAdd.next = pred.next;
pred.next = toAdd;


deleteAtIndex:
和插入同样的道理。

找到要删除节点的前驱节点。
通过改变 next 来删除节点。

// delete pred.next 
pred.next = pred.next.next;


get:
从伪头节点开始,向前走 index+1 步。

// index steps needed 
// to move from sentinel node to wanted index
for(int i = 0; i < index + 1; ++i) curr = curr.next;
return curr.val;


全部代码:

public class ListNode {int val;ListNode next;ListNode(int x) { val = x; }
}class MyLinkedList {int size;ListNode head;  // sentinel node as pseudo-headpublic MyLinkedList() {size = 0;head = new ListNode(0);}/** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */public int get(int index) {// if index is invalidif (index < 0 || index >= size) return -1;ListNode curr = head;// index steps needed // to move from sentinel node to wanted indexfor(int i = 0; i < index + 1; ++i) curr = curr.next;return curr.val;}/** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */public void addAtHead(int val) {addAtIndex(0, val);}/** Append a node of value val to the last element of the linked list. */public void addAtTail(int val) {addAtIndex(size, val);}/** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */public void addAtIndex(int index, int val) {// If index is greater than the length, // the node will not be inserted.if (index > size) return;// [so weird] If index is negative, // the node will be inserted at the head of the list.if (index < 0) index = 0;++size;// find predecessor of the node to be addedListNode pred = head;for(int i = 0; i < index; ++i) pred = pred.next;// node to be addedListNode toAdd = new ListNode(val);// insertion itselftoAdd.next = pred.next;pred.next = toAdd;}/** Delete the index-th node in the linked list, if the index is valid. */public void deleteAtIndex(int index) {// if the index is invalid, do nothingif (index < 0 || index >= size) return;size--;// find predecessor of the node to be deletedListNode pred = head;for(int i = 0; i < index; ++i) pred = pred.next;// delete pred.next pred.next = pred.next.next;}
}


复杂度分析

时间复杂度:
addAtHead:O(1)
addAtInder,get,deleteAtIndex: O(k),其中 k指的是元素的索引。
addAtTail:O(N),其中 N 指的是链表的元素个数。
空间复杂度:所有的操作都是 O(1)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/443994.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《一天聊一个设计模式》 策略

9. 策略&#xff08;Strategy&#xff09; Intent 定义一系列算法&#xff0c;封装每个算法&#xff0c;并使它们可以互换。 策略模式可以让算法独立于使用它的客户端。 Class Diagram Strategy 接口定义了一个算法族&#xff0c;它们都实现了 behavior() 方法。Context 是…

如何在eclipse jee中创建Maven project并且转换为Dynamic web project

转自&#xff1a;http://www.javaniu.com/maven-jee-dynamic-web-project.htm 注意:该文档只针对以下eclipse版本&#xff0c;如图 一.在eclipse的官方站点下载eclipse jee版本,地址http://www.eclipse.org/downloads/download.php?file/technology/epp/downloads/release/ind…

《一天聊一个设计模式》 抽象工厂

4. 抽象工厂&#xff08;Abstract Factory&#xff09; Intent 提供一个接口&#xff0c;用于创建 相关的对象家族 。 Class Diagram 抽象工厂模式创建的是对象家族&#xff0c;也就是很多对象而不是一个对象&#xff0c;并且这些对象是相关的&#xff0c;也就是说必须一起…

精华Java问题总结

当时在网上汇总了不知多少面试和基础题&#xff0c;弄了个精华总结。 1、一个".java"源文件中是否可以包括多个类&#xff08;不是内部类&#xff09;&#xff1f;有什么限制&#xff1f; 可以有多个类&#xff0c;但只能有一个public的类&#xff0c;并且public的类…

复习Java的精华总结

小白和老手都应该看看的总结 输入 java.util.Scanner 是 Java5 的新特征&#xff0c;我们可以通过 Scanner 类来获取用户的输入。 下面是创建 Scanner 对象的基本语法&#xff1a; Scanner s new Scanner(System.in); 使用方法如下&#xff1a; //对应类型用对应的方法接…

超硬核!躺进BAT以后我总结了出现最多的15道数组题

作为一个硬核作者&#xff0c;绝不和你扯废话&#xff0c;干货无套路送你 题目一&#xff1a; 给定一个数组arr&#xff0c;求出需要排序的最短子数组长度 要求&#xff1a; 时间o(n),空间o(1) 思路&#xff1a; 有序的数组中&#xff0c;任意一个数字&#xff0c;一定小于左…

《关于我的那些面经》滴滴Java岗(附答案)

手撕单例模式 所谓单例&#xff0c;就是整个程序有且仅有一个实例。该类负责创建自己的对象&#xff0c;同时确保只有一个对象被创建。 在Java&#xff0c;一般常用在工具类的实现或创建对象需要消耗资源。特点&#xff1a;类构造器私有、持有自己类型的属性、对外提供获取实…

《关于我的那些面经》——百度后端(附答案)

作者保证&#xff0c;本系列全是纯干货真实记录&#xff0c;绝对不是某些营销号瞎编乱造的面试。 一、公司的简介 百度是全球最大的中文搜索引擎&#xff0c;是中国最大的以信息和知识为核心的互联网综合服务公司&#xff0c;更是全球领先的人工智能平台型公司。2000年1月1日创…

《兔兔公司的历史》那些年,百度的荣耀和沉沦

这是全站最硬核的兔子700文章后的第一篇软文&#xff0c;觉得喜欢的同学可以三连一波&#xff0c;如果大家喜欢&#xff0c;我会出公司的历史系列、互联网大佬系列、产品经理系列&#xff0c;大家喜欢哪个呢&#xff1f; 百度公司的发展趋势 还记得南宋词人辛弃疾的那首词吗&a…

这篇不讨好任何人的回忆录,记录了我从双非学校到BAT/TMD六offer的原因

注&#xff1a;给我想个新名字好不好呀&#xff0c;采用了直接发百元红包&#xff01;没别的&#xff0c;想让大家认识兔兔rabbit&#xff0c;说一下自己的经验教训&#xff0c;应该会对很多人有帮助。 一、前言 在今年&#xff0c;我要毕业了&#xff0c;基本结束了大学生活&…

《兔子的大厂面经合集》朋友面神策数据库,第五个问题不会,直接再见(1)

这个系列计划收集几百份朋友和读者的面经&#xff0c;作者合集方便查看&#xff0c;各位有面经屯着可以联系我哦 写数据库还真不是人人都能干的&#xff0c;硬是一道别的题都没问。

兔子,撒币

作为最硬核的你兔老大&#xff0c;我狠起来连自己都骂 一、原力第一 哈哈当然不是骂自己啦哈哈&#xff0c;其实是最近csdn出了一个活动&#xff1a;原力计划s3&#xff0c;弄得我现在整天想着&#xff0c;给你们发钱。发书。发资料。 对&#xff0c;就是这个玩意&#xff1a…

超硬核!数据库学霸笔记,考试/面试随便秒杀

废话不多说&#xff0c;上干货是兔老大的传统了&#xff0c;收藏就完事了。 目录 数据库系统概论 四个基本概念 数据模型 数据库系统结构 数据库系统模式的概念 数据库系统的三级模式结构 数据库的二级映像功能与数据的独立性 数据库系统的组成 关系 关系模式 关系数…

腾讯面试Android必问11题,我说的,不信就来看看

众所周知兔子啥都会那么一点&#xff0c;不收藏等着干啥呢 1、是否使用过本地广播&#xff0c;和全局广播有什么差别&#xff1f; 引入本地广播的机制是为了解决安全性的问题&#xff1a; 正在发送的广播不会脱离应用程序&#xff0c;比用担心app的数据泄露&#xff1b;其他的…

超硬核!我统计了BAT笔试面试出现频率最高的五道题,学会了总能碰到一道

所以说不要怕算法&#xff0c;简单的题反而出现的频率最高&#xff0c;不一定非要写个几百道才面试 两数之和 给定一个整数数组 nums 和一个目标值 target&#xff0c;请你在该数组中找出和为目标值的那 两个 整数&#xff0c;并返回他们的数组下标。 你可以假设每种输入只会…

不骗你,全网首创的超硬核的万字SQL题

因为上次发了数据库原理总结&#xff0c;浏览快上万了&#xff0c;所以把我总结的题目 也送给大家 上次的数据库原理总结 一&#xff0e;根据员工工资计算其个人所得税&#xff0c;3000元为起征点&#xff0c;超出3000元的部分按照10%的比例征收个人所得税&#xff0c;例如&…

学姐腾讯产品面经

顺利拿到sp offer&#xff0c;不服不行&#xff0c;不是这块料呀 系列文章历史&#xff1a; 朋友面神策数据库&#xff0c;第五个问题不会&#xff0c;直接再见 美女学姐面了美团阿里京东&#xff0c;这些经验实在太真实了 首先&#xff0c;来个背景介绍&#xff1a; 腾讯实…

关于阿里云服务器本地访问不了的问题

一&#xff1a;前几天公司购买了一台阿里云服务器&#xff0c;让我把之前的项目都移到阿里云服务器上&#xff0c;我为此专门的研究了一下阿里云服务器的基本操作和安装流程&#xff0c;这里我说一下我们公司的服务器配置如下&#xff1a; 系统就配置就是这个情况&#xff0c;下…

超硬核!十万字c++题,让你秒杀老师和面试官(上)

我发现呀&#xff0c;这大家对面试题的需求还是很大的&#xff0c;这里总结了上千道知识点&#xff0c;能换您一个收藏吗 C 引用和指针的区别&#xff1f; 指针是一个实体&#xff0c;需要分配内存空间。引用只是变量的别名&#xff0c;不需要分配内存空间。 引用在定义的时候…

当年,学姐把这份Java总结给我,让我在22k的校招王者局乱杀

可以说&#xff0c;学姐给我的这份文档真的把我的知识查漏补缺&#xff0c;面试问到了好多&#xff0c;值得收藏。 并发编程 一.Executor 为什么使用线程池&#xff1a;手动创建线程耗费性能&#xff0c;不利于管理。 首先创建线程池有两种方式&#xff1a;使用Executors工厂…