当前位置:网站首页>【js】-【链表-应用】-学习笔记
【js】-【链表-应用】-学习笔记
2022-06-24 19:42:00 【有趣的学习】
【js】-【链表-应用】-学习笔记
声明:本笔记是根据掘金小册总结的,如果要学习更多细节,请移步https://juejin.cn/book/6844733800300150797
1 链表的合并
描述:
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有结点组成的
输入:
1->2->4,
1->3->4
输出:
1->1->2->3->4->4
思路:
下图中红色箭头表明穿针的过程与方向
- 新建一个头节点,建立一个指针
cur,作为针- 把比较小的那个节点串起来,指针向前移,当前 cur指针也往前移
- 最后处理没有走完的链表,拼在最后
const mergeTwoLists = function(l1, l2) {
#1 定义头结点,确保链表可以被访问到
let head = new ListNode()
// cur 这里就是咱们那根“针”
let cur = head
// “针”开始在 l1 和 l2 间穿梭了
while(l1 && l2) {
# 2.1如果 l1 的结点值较小,先串起 l1 的结点,l1向前走
if(l1.val<=l2.val) {
cur.next = l1
l1 = l1.next
} else {
#2.2 如果l2 较小时,串起 l2 结点,l2 向前一步
cur.next = l2
l2 = l2.next
}
#3 “针”在串起一个结点后,也会往前一步
cur = cur.next
}
#4 处理链表不等长的情况
cur.next = l1!==null?l1:l2
// 返回起始结点
return head.next
};
2 链表结点的删除
1. 删除所有重复的元素
描述:
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
输入:
1->1->2
输出:1->2
输入:
1->1->2->3->3
输出:1->2->3
const deleteDuplicates = function(head) {
#1 设定 cur 指针,初始位置为链表第一个结点
let cur = head;
#2 遍历链表
while(cur != null && cur.next != null) {
if(cur.val === cur.next.val) {
# 2.1 若当前结点和它后面一个结点值相等(重复),删除靠后的那个结点(去重)
cur.next = cur.next.next;
} else {
# 2.2 若不重复,继续遍历
cur = cur.next;
}
}
return head;
};
2 删除所有含有重复数字的结点
描述:
给定一个排序链表,删除所有含有重复数字的结点,只保留原始链表中 没有重复出现的数字
输入:
1->2->3->3->4->4->5
输出:1->2->5
输入:
1->1->1->2->3
输出:2->3
思路:
链表的第一个结点,因为没有前驱结点,导致我们面对它无从下手。这时我们就可以用一个dummy结点来解决这个问题。
1 定义dummy结点,指向头结点,cur从dummy遍历
2. 遇到一样的,记录val的值,开始循环遍历,把一样的都删除。不一样则跳过
3 返回dummy.next,即链表的起始节点
const deleteDuplicates = function(head) {
#1 极端情况:0个或1个结点,则不会重复,直接返回
if(!head || !head.next) {
return head
}
#2 dummy 登场,dummy 永远指向头结点
let dummy = new ListNode()
dummy.next = head
#3 cur 从 dummy 开始遍历
let cur = dummy
// 当 cur 的后面有至少两个结点时
while(cur.next && cur.next.next) {
// 对 cur 后面的两个结点进行比较
if(cur.next.val === cur.next.next.val) {
// 若值重复,则记下这个值
let val = cur.next.val
// 反复地排查后面的元素是否存在多次重复该值的情况
while(cur.next && cur.next.val===val) {
// 若有,则删除
cur.next = cur.next.next
}
} else {
// 若不重复,则正常遍历
cur = cur.next
}
}
// 返回链表的起始结点
return dummy.next;
};
dummy结点,模板代码
const dummy = new ListNode()
// 这里的 head 是链表原有的第一个结点
dummy.next = head
3 删除链表的倒数第 N 个结点(快慢指针)
描述:
给定一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
给定一个链表:
1->2->3->4->5, 和n = 2.
当删除了倒数第二个结点后,链表变为1->2->3->5.
思路:
- 定义dummy结点作为头结点的前驱, 快慢指针都从dummy开始
- 快指针先走n步,
- 快慢指针开始同步走,
- 删除慢指针的后继,即倒数第n个结点
- 返回dummy.next,即头结点
const removeNthFromEnd = function(head, n) {
#1 初始化 dummy 结点,指向头结点
const dummy = new ListNode()
dummy.next = head
#2 初始化快慢指针,均指向dummy
let fast = dummy
let slow = dummy
#3 快指针闷头走 n 步
while(n!==0){
fast = fast.next
n--
}
#4 快慢指针一起走
while(fast.next){
fast = fast.next
slow = slow.next
}
#5 慢指针删除自己的后继结点
slow.next = slow.next.next
// 返回头结点
return dummy.next
};
4.0 链表的反转(多指针)
描述:
定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点
输入:
1->2->3->4->5->NULL
输出:5->4->3->2->1->NULL
思路:
- 前驱结点
pre,当前结点cur,后继结点nextnext指向pre,然后pre和cur都继续后移- 最后返回
pre,就是新链表的头结点
const reverseList = function(head) {
#1 初始化前驱结点为 null
let pre = null;
#2 初始化目标结点为头结点
let cur = head;
#3 只要目标结点不为 null,遍历就得继续
while (cur !== null) {
// 记录一下 next 结点
let next = cur.next;
// 反转指针
cur.next = pre;
// pre 往前走一步
pre = cur;
// cur往前走一步
cur = next;
}
// 反转结束后,pre 就会变成新链表的头结点
return pre
};
4.1 局部反转一个链表
描述:
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
输入:
1->2->3->4->5->NULL, m = 2, n = 4
输出:1->4->3->2->5->NULL
思路
- 先定义
dummy,找到m的前驱,并保存下来lefthead- 从
m作为pre,cur指向pre.next开始翻转- 把
leftHead指向pre,start指向cur
// 入参是头结点、m、n
const reverseBetween = function(head, m, n) {
// 定义pre、cur,用leftHead来承接整个区间的前驱结点
let pre,cur,leftHead
#1 dummy结点
const dummy = new ListNode()
dummy.next = head
#2.0 p是一个游标,用于遍历,最初指向 dummy,往前走 m-1 步,走到整个区间的前驱结点处
let p = dummy
for(let i=0;i<m-1;i++){
p = p.next
}
#2.1 缓存这个前驱结点到 leftHead 里
leftHead = p
let start = leftHead.next // start 是反转区间的第一个结点
pre = start// pre 指向start
cur = pre.next // cur 指向 start 的下一个结点
#3 开始重复反转动作
for(let i=m;i<n;i++){
let next = cur.next// 记录一下 next 结点
cur.next = pre // 反转指针
pre = cur// pre 往前走一步
cur = next // cur往前走一步
}
#4 leftHead 的后继结点此时为反转后的区间的第一个结点
leftHead.next = pre
start.next=cur // 将区间内反转后的最后一个结点 next 指向 cur
return dummy.next // dummy.next 永远指向链表头结点
};
5 判断链表是否成环
- 改变结点,
flag
const detectCycle = function(head) {
while(head){
if(head.flag){
return head;
}else{
head.flag = true;
head = head.next;
}
}
return null;
};
2. 可以用map模拟 (个人喜欢,牢记)
const detectCycle = function(head) {
const visited = new Map();
while(head){
if(visited.has(head)){
return head;
}else{
visited.set(head)
head = head.next;
}
}
return null;
};
- 快慢指针
快指针走两步,慢指针走一步
如果相等了就有环
const detectCycle = function(head) {
if(!head) return null;
let slow=head,fast=head;
#1 快指针没到头就继续
while (fast !== null) {
#2 慢指针走一步,快指针走两步
slow = slow.next;
if (fast.next !== null) {
fast = fast.next.next;
} else {
return null;
}
#3 如果快慢指针相遇
if (fast === slow) {
let ptr = head;
while (ptr !== slow) {
ptr = ptr.next;
slow = slow.next;
}
return ptr;
}
}
return null;
};
我们再额外使用一个指针
ptr。
起始,它指向链表头部
;随后,它和slow每次向后移动一个位置。最终,它们会在入环点相遇。
边栏推荐
- Financial management [3]
- 推送Markdown格式信息到釘釘機器人
- Research and investment strategy report on China's building steel structure anticorrosive coating industry (2022 Edition)
- 剑指 Offer 13. 机器人的运动范围
- Selection (025) - what is the output of the following code?
- 【Laravel系列7.9】测试
- C#学习两年的增删改查和C#导入导出(去重)案例
- Dig deep into MySQL - resolve the clustered index / secondary index / federated index of InnoDB storage engine
- The extra points and sharp tools are worthy of the trust | know that Chuangyu won the letter of thanks from the defense side of the attack and defense drill!
- Spark 离线开发框架设计与实现
猜你喜欢

Online group chat and dating platform test point

03_SpingBoot 核心配置文件

go Cobra命令行工具入门

Uncover the secrets of Huawei cloud enterprise redis issue 16: acid'true' transactions beyond open source redis

vulnhub Vegeta: 1

花房集团二次IPO:成于花椒,困于花椒

Blogs personal blog test point (manual test)
![[Wuhan University] information sharing of the first and second postgraduate entrance examinations](/img/ec/884e656a921e20a5679a2960c9ac4d.jpg)
[Wuhan University] information sharing of the first and second postgraduate entrance examinations
![[postgraduate entrance examination English] prepare for 2023, learn list8 words](/img/25/d1f2c2b4c0958d381db87e5ef96df9.jpg)
[postgraduate entrance examination English] prepare for 2023, learn list8 words
![[laravel series 7.9] test](/img/49/4b470a8b309bab4a83eed930dcce65.png)
[laravel series 7.9] test
随机推荐
Epics record reference 2 -- epics process database concept
2022 simulated 100 questions and simulated examination of high-altitude installation, maintenance and demolition
laravel 消息队列
【文本数据挖掘】中文命名实体识别:HMM模型+BiLSTM_CRF模型(Pytorch)【调研与实验分析】
Docker installation redis- simple without pit
Research Report on terahertz imaging system industry - market status analysis and development prospect forecast
Research Report on market evaluation and investment direction of Chinese dermatology drugs (2022 Edition)
Sword finger offer 42 Maximum sum of successive subarrays
EPICS記錄參考3 -- 所有記錄都有的字段
京东618会议平板排行榜公布,新锐黑马品牌会参谋角逐前三名,向国货老大华为学习
laravel 验证器的使用
Spark 离线开发框架设计与实现
剑指 Offer 13. 机器人的运动范围
C#学习两年的增删改查和C#导入导出(去重)案例
Research Report on market supply and demand and strategy of ceiling power supply device industry in China
Online group chat and dating platform test point
How to submit the shopee opening and settlement flow?
【nvm】
[WSL] SSH Remote Connection and host port forwarding configuration
The extra points and sharp tools are worthy of the trust | know that Chuangyu won the letter of thanks from the defense side of the attack and defense drill!




