数据结构——Javascript中的链表(下)

前言

在上文中我们介绍了链表的概念以及如何在链表中执行增加,删除,查找的操作。以及链表与数组相比的优点与缺点。我们将在本文介绍如何使用链表解决LeetCode中的算法题。

正文

我们先看第一题

js 复制代码

映入眼帘的是合并两个有序列表的标题,在知道链表的一些操作后面对这个题目先想想思路:我们要把6个结点串在一起,我们先将两个链表的第一个结点大小进行比较,穿上小的然后再将后面的结点与另一个链表上的结点进行比较,以此类推。最后剩余一个链表的结点不会进行比较,因为它是最大的结点

js 复制代码
function ListNode(val, next) {
    this.val = (val === undefined ? 0 : val)
    this.next = (next === undefined ? null : next)
}

var mergeTwoLists = function (list1, list2) {
    let head = new ListNode()
    let cur = head

    while (list1 && list2) {
        if (list1.val <= list2.val) {
            cur.next = list1
            list1 = list1.next
        } else {
            cur.next = list2
            list2 = list2.next  
        }
        cur = cur.next
    }
  

    cur.next = list1 !== null ? list1 : list2

    return head.next
};

在这里我们使用了 while 循环,在 list1 和 list2 都非空时继续执行。循环内部比较两个链表当前节点的值: 如果 list1 当前节点的值小于等于 list2 当前节点的值,就会把 list1 的当前节点接到 cur 节点之后,并将 list1 指针移动到下一个节点。 否则,把 list2 的当前节点接到 cur 节点之后,并将 list2 指针移动到下一个节点。 当循环结束时,说明至少有一个链表已经遍历完。这时候会直接将没有遍历完的链表的剩余部分接到 cur.next,因为剩余部分已经是升序的,所以可以直接附加到结果链表末尾。

最后,返回新链表的头节点,即 head.next,因为在初始化时 head 节点的值是无意义的占位符,实际合并结果从 head.next 开始。

题二

这道题是删除链表的结点,在上文中我们介绍过删除链表结点的操作。那么对于这道题,我们该如何去删除目标值所在的结点呢?

js 复制代码
val = 5

head = {
    val: 4,
    next: {
        val: 1,
        next: {
            val: 5,
            next: {
                val: 9,
                next: null
            }
        }
    }
}

假如这是给定的链表,这段代码给出val = 5,那么我们要让1的next直接指向9

js 复制代码
function ListNode(val) {
    this.val = val;
    this.next = null;
}
var deleteNode = function(head, val) {
    let cur = head 
    if(cur.val ===val){  // 要移除头结点
        head = head.next
    }

    while(cur && cur.next) {
        if(cur.next.val === val){
          // cur.next就是要被移除的节点
          cur.next = cur.next.next
             
        }


        cur = cur.next
    }

    return head;
};

因为我们要遍历这里链表,最后要返回头结点。所以我们先直接在最后面return head; 如果头节点就是要删除的节点,那么就直接将 head 指向下一个节点,这样相当于删除了原头节点

js 复制代码
      if(cur.next.val === val){
          // cur.next就是要被移除的节点
          cur.next = cur.next.next        
        }

然后排除了头结点就是目标结点的情况下,我们就进入循环遍历这个链表直到找到目标结点,然后就将 cur.next 指向 cur.next.next,从而跳过当前的 cur.next 节点。

题三

这一题与上面一题相似度很高,在这里我们要去删除链表中重复的结点

js 复制代码
function ListNode(val, next) {
    this.val = (val === undefined ? 0 : val)
    this.next = (next === undefined ? null : next)
}
var deleteDuplicates = function (head) {
    if (!head || !head.next) return head; // 如果链表为空或只有一个元素,直接返回
    let cur = head;

    while (cur.next) {
        if (cur.val === cur.next.val) { // 发现重复元素
            cur.next = cur.next.next; // 删除当前节点的下一个节点
        } else {
            cur = cur.next; // 没有重复,移动到下一个节点
        }
    }

    return head;
};

在这段代码中我们先判断链表是否为空或者只有一个头结点,如果是的话就直接返回。不是的话就会进入循环当找到相同的元素时,就会 cur.next = cur.next.next;跳过这个重复的结点

总结

在上文学习了链表的相关知识后,这篇文章就是关于链表的实战,如果这些题目都没有问题的话,那你就基本掌握了链表这个知识点了。这篇文章对你有帮的话,那就留下你的点赞和收藏吧 :-)

相关推荐
panxianren3 小时前
Bun 1.4 的 bun test --parallel 将 4 秒的测试套件缩短到约 1 秒
java·javascript
陈随易5 小时前
bm2,Node.js 与 Bun 项目部署新选择
前端·后端·程序员
奋发向前wcx5 小时前
CSP-J复赛模拟赛4 王晨旭补题 2026.10.5
算法
可乐鸡翅yeah_6 小时前
FFmpeg 生成 HLS 独立分片 independent‑segments 参数到底有什么用
javascript·ffmpeg·音视频·safari·m3u8
福兮说6 小时前
canvas 旋转图片的六个坑:四角被裁、Math.ceil 多出 1px 黑边、JPG 角发黑、翻转方向反了
前端·javascript·图像处理·canvas
念何架构之路7 小时前
zap采样器与性能优化内幕
算法·性能优化·哈希算法
Ai-_Man7 小时前
您您这可以把Grok的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。AI导出鸭
javascript·人工智能·ai·小程序·电脑
传人once7 小时前
多图片上传预览功能如何写
前端·css·html·jquery·html5
Eric.468 小时前
Wan‑Animate+MiniMax-H3 本地部署 AI 漫剧流水线:8G 显存动作迁移与动态分镜工程实战
前端·人工智能·comfyui·ai漫剧
liangshanbo12158 小时前
JavaScript 异步核心主线
javascript·事件循环·异步操作