【我的力扣战纪】链表-2-两数相加

379 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

有人相爱,有人夜里开车看海,我却leetcode第二题都做不出来...

题目描述

原题链接:2.两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

/ 测试用例一 / 
输入: l1 = [2,4,3], l2 = [5,6,4]
输出: [7,0,8]
解释: 342 + 465 = 807
-----------------------------------
/ 测试用例二 / 
输入: l1 = [0], l2 = [0]
输出: [0]
-----------------------------------
/ 测试用例三 / 
输入: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出: [8,9,9,9,0,0,0,1]

思路

  • 链表是用next指针连在一起的元素列表,JavaScript中没有链表,我们可以用Object模拟链表
//创建链表的构造函数
function ListNode(val, next) {
   this.val = val ?? 0
   this.next = next ?? null
 }
  • 首先肯定是新建一个虚拟的节点,然后把入参l1l2两个链表同位val之和放入虚拟节点的后面
  • 判断每次的和有溢出的话,就存进一个自由变量,留给下一位相加
  • 下一次l1l2链表同位val之和相加要把上一次的进位结算进去
  • 思维发散,递归、循环都写一遍

Code

/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/

/**  循环版  */
const addTwoNumbers1 = (l1, l2)=>{
   //创建一个新链表
   const node = new ListNode()
   //创建当前链表节点变量、进位值变量、同位之和变量
   let current = node, add = 0, sum = 0;
   
   //当且仅当l1和l2的节点数值都为null才结束循环
   while (l1 || l2) {
       sum = (l1 ? l1.val : 0) + (l2 ? l2.val : 0) + add
       current.next = new ListNode(sum % 10)  //当链表同位之和超过10 就取溢出值
       current = current.next
       add = sum >= 10 ? 1 : 0
       l1 && (l1 = l1.next)
       l2 && (l2 = l2.next)
   }
   add && (current.next = new ListNode(add))
   return node.next
};

/**  递归版  */
const addTwoNumbers2 = (l1,l2)=> dfs(l1, l2, 0)
const dfs=(l1,l2,add)=>{
   //如果l1,l2为空,进位数为0,递归结束
 if (!l1 && !l2 && add === 0) {
   return null
 }
 const sum = (l1 ? l1.val : 0) + (l2 ? l2.val : 0) + add
 const node = new ListNode(sum % 10)
 node.next = dfs(l1 ? l1.next : null, l2 ? l2.next : null, Math.floor(sum / 10));
 return node
}

复杂度分析

  • 时间复杂度: O(max(m,n)) n取最长链表的长度
  • 空间复杂度:循环版O(1) ;递归版O(max(m,n))

image.png