首页 > 其他分享 >JS刷力扣-链表【持续跟新】

JS刷力扣-链表【持续跟新】

时间:2024-10-09 21:19:05浏览次数:12  
标签:curr val next 链表 let ListNode JS 刷力

力扣的链表归类

2.两数相加【链表+递归】

前置知识:
1. 链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。
2. 链表的入口节点称为链表的头结点也就是head。
在这里插入图片描述
leetcode里 new Listnode()就是定义一个空节点的链表
定义一个节点值为空的链表let dummy = new ListNode()节点值为空也相当于是定义了一个空链表
定义一个节点值非空的链表xx = new ListNode(val)
a. 取链表的当前值xx.val
b. 取之后的值:当前值之后的那个值赋值给当前的值xx = xx.next

思路:

  1. 定义一个变量carry用来存储进位;定义一个sum变量
  2. 两链表相加要生成一个新的链表,新的链表的头部创建一个dummy节点用来占位(两个节点相加会生成一个新的节点,新的节点需要一个头部然后剩下的节点就可以一个个串在后面)
  3. 让最初的curr节点指向dummy节点;没相加生成一个新的节点curr往前进一位
  4. 判断两个链表相加得到的是个位数还是两位数;大于10则对sum取余sum%10得到个位数,然后将sum除10并向下取整Math.floor(sum/10)后的值赋给carry(这一步每次都要进行)
  5. 两个链表的下一次相加要再加上carry,然后将carry置为0
  6. 这一系列操作完成后还需要最后再检查一次carry,如果值为0则不用操作,如果值不为0要在新链表最后再加一个节点值为1
    有则返回结果
    没有则把num[i]当做key,i当做value放入map中
    (这里主要是因为使用map.has()进行判断的时候判断的是key是否存在,所以把num[i]当作key放入才能判断有没有这个元素,其次get()返回的是value,这样反着存,得到的就是num[i]的下标)
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function(l1, l2) {
    // 生成一个新的链表节点 头部之前指向dummy dummy用来占位
    let dummy = new ListNode()
    // 创建一个用来遍历链表的变量 cur
    let cur = dummy
    // 生成一个用来存放进位的变量
    let carry = 0
    // 判断 输入的两个链表都非空
    while(l1 !== null || l2 !== null){
        let sum = 0  // 用来统计两个链表的和
        // 判断两个链表都非空 非空则用sum加上
        if(l1 !== null){
            sum += l1.val
            l1 = l1.next
        }
        if(l2 !== null){
            sum += l2.val
            l2 = l2.next
        }
        sum += carry
        // 首先除10取余 让cur的下一个节点值为全部相加后的个位数
        // 然后除10并向下取整 carry存放有没有进位
        // 最后让cur指向下一个节点
        cur.next = new ListNode(sum % 10)
        carry = Math.floor(sum/10)
        cur = cur.next
        // console.log(dummy.next)    //[7] [7,0] [7,0,8]
    }
    if(carry > 0){
        cur.next = new ListNode(carry)
    }
    return dummy.next
    // console.log(dummy.next)   [7,0,8]
};

19.删除链表的倒数第 N 个结点【链表+双指针】

前置问题

  1. 单向链表只能从前往后遍历
  2. 可以用链表长度-n+1知道要删除的结点正向的位置,但链表长度未知,可以遍历计数得到其长度,进阶尝试一次扫描完成题目
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} n
 * @return {ListNode}
 */
var removeNthFromEnd = function(head, n) {
    // 定义一个dummy节点 避免出现链表长度为1并且n也为1时无法处理的情况
    let dummy = new ListNode()
    dummy.next = head
    // 让n1和n2两个指针都指向dummy
    let n1 = dummy
    let n2 = dummy

    // // 让n2领先n1 n+1个身位的情况 就是当n2指向空结点了 n1指向要删掉的结点的前一个结点 下一步让当前n1等于n1.next.next
    // for(let i = 0; i <=n; i++){
    //     n2 = n2.next
    // }
    //  while(n2 !== null){
    //     n1 = n1.next
    //     n2 = n2.next
    // }

    // 让n2领先n1 n个身为的情况 就是当n2.next指向空结点了 n1指向要删掉的结点的前一个结点
    for(let i = 0; i <n; i++){
        n2 = n2.next
    }
    while(n2.next !== null){
        n1 = n1.next
        n2 = n2.next
    }
    // n2为null之后 n1指向的就是n的前一位
    n1.next = n1.next.next

    return dummy.next
};

21.合并两个有序链表【链表+递归】

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} list1
 * @param {ListNode} list2
 * @return {ListNode}
 */
var mergeTwoLists = function(list1, list2) {
    // 创建一个新的链表的头结点 dummy是几乎链表题都要出现的
    let curr = new ListNode()
    let dummy = curr
    // 当两个链表都不为空时,比较大小,然后把对应值加到curr节点后面并且移动curr当前指向的结点
    while(list1 !== null && list2 !== null){
        if(list1.val < list2.val){
            // 这里是把list1整个都给到curr.next了,但是因为要排序所以要在for循环里不停调整节点的指向
            curr.next = list1
            list1 = list1.next
            // console.log(curr,list1)  [1,1,2,4] [2,4] ;[1,2,4] [4]
        }else{
            curr.next = list2
            list2 = list2.next
        }
        curr = curr.next
    }
    // 其中一个链表为空时 直接把另一个不为空的链表加在后面
    if(list1 !== null){
        curr.next = list1
    }
    if(list2 !== null){
        curr.next = list2
    }
    return dummy.next
};

24.两两交换链表中的节点【链表】

重点是这六步 交换的顺序按照链表顺序来 先改变curr指向;再改变n1指向;再改变n2指向
 let n1 = curr.next
 let n2 = curr.next.next
 curr.next = n2
 n1.next = n2.next
 n2.next = n1
 curr = n1
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var swapPairs = function(head) {
    let dummy = new ListNode()
    dummy.next = head
    let curr = dummy
    while(curr.next !== null && curr.next.next !== null){
        let n1 = curr.next
        let n2 = curr.next.next
        curr.next = n2
        n1.next = n2.next
        n2.next = n1
        curr = n1
    }
    return dummy.next
};

83.删除排序链表中的重复元素【链表】

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var deleteDuplicates = function(head) {
    let current = head
    while(current !== null && current.next !== null){
        if(current.val === current.next.val){
            current.next = current.next.next
        }else{
            current = current.next
        }
    }
    return head
};

82. 删除排序链表中的重复元素 II【链表、双指针】

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var deleteDuplicates = function(head) {
    let dummy = new ListNode()
    dummy.next = head
    let cur = dummy
    while(cur.next && cur.next.next) {
        if (cur.next.val === cur.next.next.val) {
            const x = cur.next.val
            while(cur.next && cur.next.val === x) cur.next = cur.next.next
        }else {
            cur = cur.next
        }
    }
    return dummy.next
};

206.反转链表【链表 递归】

链表相关的题大部分都是操作指针
可以借助栈后进先出的特点实现反转,但是需要多开一个数组,会占据O(n)空间
思路

  1. 用三个指针实现 prev、curr、next
  2. prev永远指向curr和next的前一个,curr和next开始指向同一个结点;
  3. for循环遍历,先让next后移,然后让curr.next指针指向prev,然后将prev迁移,最后让curr也指向next
  4. 由于prev和next的操作都是基于curr的位置来实现,所以第一步是改变next;第二步是改变prev;最后才能改变curr
  5. next在这里的作用主要是先占据curr.next的那个位置后边再接curr过来。
  6. 主要的四步
next = curr.next
curr.next = prev
prev = curr
curr = nexr
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    let curr = head
    let prev = null
    let next = head
    while(curr !== null){
        // es6解构赋值的新写法 这种写法不再需要next作为临时值
        // 因为这种结构赋值是同一时间操作完的 所以他不需要中间变量
        [curr.next, prev, curr] = [prev, curr, curr.next]
        // [curr.next, curr, prev] = [prev,  curr.next,curr]


        // // 传统写法
        // next = curr.next
        // curr.next = prev
        // prev = curr
        // curr = next
    }
    return prev
};

92 反转链表II

反转链表I的基础上又多加了两个指针用来标记位置

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} left
 * @param {number} right
 * @return {ListNode}
 */
var reverseBetween = function(head, left, right) {
    let prev = null
    let curr = head
    let next = head
    // for循环让他们都到达开始得位置
    for(let i = 1; i < left; i++){
        prev = curr
        curr = curr.next
    }
    // 让这两个指针占住后续重新连接链表得关键位置
    let curr2 = curr
    let prev2 = prev

    // 像反转链表I一样对要操作的部分进行反转
    for(let i = left;i <= right; i++){
        next = curr.next
        curr.next = prev
        prev = curr
        curr = next
    }

    // 判断以下是不是从第一个结点就开始进行链表反转的
    if(prev2 !== null){  //m > 1
        prev2.next = prev
    }else{
        head = prev
    }
    curr2.next = curr
    return head
};

标签:curr,val,next,链表,let,ListNode,JS,刷力
From: https://blog.csdn.net/qq_43536901/article/details/142796955

相关文章

  • Vue.js点餐页面完整教程:从零开始实现功能齐全的点餐系统” “轻松上手!用Vue.js打造响
    效果图:目录一、创建Vue项目二、构建基本页面结构三、使用CSS美化页面四、实现页面交互功能五、完整代码展示六、结语步骤点餐页面是餐饮类应用的重要组成部分。它不仅要美观,还需要具备良好的交互体验。今天,我们将使用Vue.js和CSS从零开始制作一个响应式点餐页面,......
  • nodeJS构建错误——digital envelope routines::unsupported
    最近正在调研开源工作流项目,从github上克隆的代码,执行npmrundev报错。错误如下:查找原因出现了问题,自然要想办法解决。在网上搜索了一圈,发现该问题早已出现,一般描述的大致原因就是:当 nodejs 升级到17+版本以后,开始支持 OpenSSL3.0,而 OpenSSL3.0 对各种摘要算法做......
  • 基于nodejs+vue移动购物管家app[开题+源码+程序+论文]计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着移动互联网技术的迅猛发展,智能手机已成为人们日常生活中不可或缺的一部分。在这一背景下,移动购物逐渐取代了传统购物方式,成为现代消费的主流模式。消费......
  • 基于nodejs+vue移动互联时代的设备管理系统[开题+源码+程序+论文]计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着移动互联网技术的飞速发展,各类智能设备在日常生产和生活中的应用日益广泛。从智能手机到可穿戴设备,从工业控制设备到智能家居系统,这些设备极大地提升了......
  • 基于nodejs+vue颐心家政服务网站[开题+源码+程序+论文]计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着现代生活节奏的加快,越来越多的家庭面临着时间管理和家务分配的挑战。传统的家政服务虽然在一定程度上缓解了这一压力,但信息不对称、服务质量参差不齐、......
  • 原生js元素拖动效果
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metahttp-equiv="X-UA-Compatible"content="IE=edge"/><metaname="viewport"content="w......
  • Hive(六)JSON函数
    概念什么是JSONJSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成JSON是存储和交换文本信息的语法,类似XMLJSON比XML更小、更快,更易解析JSON语法数据在名称/值对中数据由,分开使用斜杠\来转义字符大括号{}保存对象......
  • 基于nodejs+vue易逛漫展[开题+源码+程序+论文]计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着动漫文化的日益普及,漫展作为一种集动漫展示、互动体验、商品交易于一体的综合性文化活动,受到了广大动漫爱好者的热烈追捧。然而,传统的漫展参与方式往往......
  • 基于nodejs+vue易买电商管理网站[开题+源码+程序+论文]计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展,电子商务已成为现代商业活动的重要组成部分。易买电商管理网站作为电子商务领域的一个重要应用,旨在提供一个高效、便捷、安全的在......
  • 基于nodejs+vue易行汽车租赁平台[开题+源码+程序+论文]计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着城市化进程的加速和人们生活水平的提高,汽车租赁作为一种便捷、灵活的出行方式,日益受到广大消费者的青睐。近年来,我国汽车租赁市场呈现出蓬勃发展的态势,......