剑指 Offer II 025. 链表中的两数相加(翻转链表)

86 阅读2分钟

每日刷题第15天 2021.1.10

链表中的两数相加

  • 难度:中等
  • 方法:链表

题目

  • 给定两个 非空链表 l1和 l2 来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
  • 可以假设除了数字 0 之外,这两个数字都不会以零开头。

示例

  • 示例1 1626420025-fZfzMX-image.png
输入: l1 = [7,2,4,3], l2 = [5,6,4]
输出: [7,8,0,7]
  • 示例2
输入: l1 = [2,4,3], l2 = [5,6,4]
输出: [8,0,7]
  • 示例3
输入: l1 = [0], l2 = [0]
输出: [0]

提示

  • 链表的长度范围为 [1, 100]
  • 0 <= node.val <= 9
  • 输入数据保证链表代表的数字无前导 0
  • 进阶: 如果输入链表不能修改该如何处理?换句话说,不能对列表中的节点进行翻转。

解法

/**
 * 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) {
  // 定义翻转链表的函数
  function reserve (head) {
    // 翻转链表实现
    // prev cur next 三个指针
    let prev = null;
    let cur = head;
    let next = null;
    // 翻转链表代码
    while (cur) {
      next = cur.next;
      cur.next = prev;
      prev = cur;
      cur = next;
    }
    return prev;
  }
  // 链表的后面一个数,没有办法找到前面的数
  // 3 - 4 - 2 - 7
  // 4 - 6 - 5

  // 2 - 4 - 3
  // 8 - 7 - 9 - 9
  // 0 - 2 - 3 - 0 - 1
  // 9 + 9 = 18 % 10 = 1
  // 翻转两个链表
  l1 = reserve(l1);
  l2 = reserve(l2);
  // console.log('l1',l1,'l2',l2);
  // 两个相加,生成一个新的链表进行输出
  // 头节点
  let head = new ListNode();
  let headAns = head;
  // 剩余的值,1表示需要进位,0表示不需要
  let rest = 0;
  // 记录相加的和
  let add = 0;
  // 控制条件:是否 / 10 = 1 或 l1和l2还有节点
  while (rest == 1 || l1 || l2) {
    add = 0;
    // 处理当前节点,需要记录下来,下次进行加
    if (l1) {
      add += l1.val;
    }
    if (l2) {
      add += l2.val;
    }
    add += rest;
    // console.log('add',add,'rest',rest);
    // 相加之后大于10 相加之后不大于10,但是加上rest后大于10
    if(parseInt(add / 10) == 1) {
      // 当前相加结果,大于10
      // console.log('大于',add % 10);
      head.val = add % 10;
      // console.log('val大于',head.val);
      // 存储下来,给下一个节点加加
      rest = 1;
    }else {
      // console.log('小于');
      // 小于10,直接存储即可
      head.val = add;
      // console.log('val小于',head.val);
      rest = 0;
    }
    // l1 空 l2 非空 rest = 1 创建
    // l1 空 l2 空 rest = 1 创建
    // l1 非空 l2 非空 rest = 1 创建
    // 不创建 l1 空 l2非空 rest = 0 
    // 不创建 l1空 l2 空 rest = 0
    // 不创建 l1非空 l2非空 rest = 0
    // 总的来说:一个非空,rest 表示是否进位
    // console.log('l1',l1,'l2',l2);
    if(!l1 && !l2 && rest) {
      // 不创建
      head.next = null;
      head = null;
    }else {
      // 创建
      // 创建当前节点
      let ans = new ListNode();
      head.next = ans;
      head = ans;
      // console.log('创建新节点');
    }
    // 变化l1和l2
    if (l1) {
      l1 = l1.next;
      // console.log('执行',l1);
    }
    if (l2) {
      l2 = l2.next;
    }
  }
  headAns = reserve(headAns);
  return headAns.next;
};
// 总结,除下来整数,需要使用parseInt()

附录

  • 三个指针进行反转链表prev\cur\next