You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
//链表的特定位置插入一个新元素insert(index,element){//首先,我们需要验证 index 是否在范围内,即小于 等于节点数,大于等于0。if(index<=this.count&&index>=0){letnode=newCreateNode(element);//我们还需要考虑head节点,当 index 为0时,头节点就要指向新传入的元素,新元素的 next 需要指向原来 head 节点。if(index===0){node.next=this.head;this.head=node;}else{//考虑完头节点,就可以使用写好的`getElementAt`方法将分别获取指定位置的上一个元素节点,以及指定位置的当前元素节点,让上一个元素节点的 next 指向 新创建的 node,新创建的 node节点的 next 指向当前元素节点就完成了插入操作。letprevious=this.getElementAt(index-1);letcurrent=previous.next;previous.next=node;node.next=current;}this.count+=1;returntrue;}returnfalse;}
头节点插入操作
中间或者尾部添加元素
leetcode 关于链表的题目
移除链表元素
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
示例 2:
链表
本文的源码可通过这里查看
链表类源码
链表是什么
链表(Linked List)可以存储有序的元素集合, 但是不同于数组,链表中的元素在内存中并不是连续放置的。每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成。下面是图片解释:
链表的一个好处是,在添加或者删除元素的时候,不需要移动其他元素,这一点数组就做不到。
链表的操作需要用到指针,访问数组时,可以随机访问其中一个元素(通过索引),而链表的访问元素需要从起点(表头)开始迭代链表直到找到所需的元素。
链表的增删改查可以抽象成现实中的火车,当我们需要往里面增加一列车厢时,需要断开两节车厢之间的连接,然后把车厢放进去,重新接上就可以了。
下面我们手动实现链表的 class类,在实现这个类前,我们需要先实现一个能够创建节点的类。
然后开始搭建链表的类函数,以下是一个骨架
尾部添加元素
要往尾部添加元素,这里有两种场景:
第一种是链表中没有元素,那么我们创建的就是头元素。
第二种是链表中有头元素,那么我们需要遍历到链表的最后一个元素,然后在它的尾部添加一个元素。如何判断尾部呢?链表的最后一个元素的 next 属性指向的是 undefined或者 null(这里我们用 null)。我们通过这个就可以判断其为尾元素。
那么我们就可以实现 push 函数
首先我们根据传入的元素创建一个新的 node 节点,然后进行判断:
如果当前不存在 head,那么创建的 node 节点就变成 head。
如果当前存在 head,那么需要遍历得到最后一个元素,把创建的节点连接到最后一个元素的 next 上。
如何遍历呢?方法是创建一个指针current,首先指向 head 节点, 如果 head 节点的 next 不为 null,那么就不是最后一个元素,我们让这个指针再指向下一个元素(当前指针所在元素的 next)即可。
从特定位置删除元素
链表的索引跟数组是一致,都是从0开始,head 位置指向的就是第0个位置。
上面的链表中的 element 的值跟索引是一致的。
下面我们实现一个 removeAt 方法,通过传入索引(index)来移除在该位置的元素。
访问链表的指定位置
区别于数组的随机访问,链表的随机访问需要用循环遍历到指定位置,所以它的时间复杂度为 O(n),下面实现一个函数能够访问到指定 index 的链表元素。
在任意位置插入元素
下面,我们需要能够在任意位置插入元素:
头节点插入操作
中间或者尾部添加元素
leetcode 关于链表的题目
移除链表元素
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
示例 2:
输入:head = [], val = 1
输出:[]
示例 3:
输入:head = [7,7,7,7], val = 7
输出:[]
提示:
列表中的节点数目在范围 [0, 104] 内
1 <= Node.val <= 50
0 <= val <= 50
题目解析:
如果要遍历链表,最好在链表的头部添加一个节点,这样可以有效减少边界条件,有助于帮助我们整理思路
删除链表元素很简单,当当前指针的 val 等于 val 时,就让上一个指针previous的 next 指向当前current指针的 next节点,切掉上层节点的连接就可以了。
如何获取 previous 指针呢?一个非常简单取巧的方法是新建一个虚拟的节点 root,连接到 head 节点上,然后让 previous 指针指向root 节点。这样每次遍历时,previous 总是在 current 之上。
这种方式很方便让我们获取 previous 指针,无需增加思维负担,思路简洁清晰。我们只需要有个印象,下次循环链表时,可以采取这样简单的方式。
反转链表
反转链表是一个经典的链表题,最简单的思路是采用栈来实现反转,以下是题目
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:
输入:head = [1,2]
输出:[2,1]
使用栈实现:
使用栈实现非常简单清晰,很多反转的题目都可以用栈实现,这里就不多解释了。
使用双指针:
双指针解题思路:
定义两个指针:pre在后,cur在前,一次走一步,直到cur为null,即到链表尾部
每次让 cur 的 next 指向 pre ,完成一次局部反转
pre指向cur,cur指向cur的下一个节点,即前进一步
The text was updated successfully, but these errors were encountered: