一日一练: 两数相加II

112 阅读1分钟

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

解题思路:翻转链表 + 逐位相加

  • 将两个链表反转
  • 从头开始每个节点依次相加,当和大于10时,要保存进位到一下次的相加;创建新节点来保存和,同时与上一次的和节点相连接
  • 当两个节点都为null时,要查看当前进位是否为0,不为0的话,继续创建节点。防止1 + 9这种情况的首位没有被计入结果。
  • 反转结果链表
var addTwoNumbers = function (l1, l2) {
  // 反转两个链表
  let l1Reversed = reverse(l1)
  let l2Reversed = reverse(l2)
  // 哨兵节点:保存结果链表的头节点
  const dummy = new ListNode()
  let pre = dummy
  let carry = 0
  while (l1Reversed !== null || l2Reversed !== null) {
    // 相同位置节点和
    let sum =
      (l1Reversed ? l1Reversed.val : 0) +
      (l2Reversed ? l2Reversed.val : 0) +
      carry
    // 创建新节点,同时与上一个节点相连接
    pre = pre.next = new ListNode(sum % 10)
    // 保存进位
    carry = (sum / 10) >> 0
    l1Reversed && (l1Reversed = l1Reversed.next)
    l2Reversed && (l2Reversed = l2Reversed.next)
  }
  // 如果都为null,单独对进位处理
  // 这个放到while的条件语句里就不用单独处理,但是会增加对carry的判断次数
  if (carry !== 0) {
    pre.next = new ListNode(carry)
  }
  // 翻转结果链表
  return reverse(dummy.next)
}

function reverse(root) {
  let cur = root
  let pre = null
  while (cur) {
    let next = cur.next
    cur.next = pre
    pre = cur
    cur = next
  }
  return pre
}