zoukankan      html  css  js  c++  java
  • 图解算法:单向链表做加法运算

    问:给出两个非空的链表,来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且每个结点只能存储一位数字。将这两个链表相加起来,返回一个新的链表,表示他们之和。

    例如:342 + 465 = 807

    两数相加这道题,处理的就是最简单的数学加法运算,只是它是建立在链表的基础之上,所以难度在于对链表的处理。

    加法运算,除了每一位的加法之外,还需要考虑进位的情况。针对这道题来说,链表的每一个结点存储一位数字,并且是基于自然数字逆序存储,也就是链头到链尾保持低到高位的顺序,这样就等于,进位的方向和单链表的方向一致。

    由于单链表的特性,没有前驱结点,无法回头。在这道题的场景下,就只需要一次 while 循环,从链头(低位)一直处理到链尾(高位),就可以解决。但是需要注意处理进位的情况,每一位结点在计算之后,需要按 10 取余数,进行存储,多的需要进位到下一结点参与运算,正好这也符合单链表的处理思路。

    那么我们就需要几个变量,一个 carry 用来记录每一位运算后的进位,还需要一个 dummy 结点,用于记录两个链表加法运算后的链表结点。

    当我们处理到最长链表最后一个结点时,还需要对 carry(进位) 进行额外的处理,如果 carry 不为 0,表示继续向高位进位,需要额外在创建一个新的结点存储进位。

    到这里就讲解清晰了,直接上代码。

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
      // 计算结果存储的 dummy 结点
      ListNode dummy = new ListNode(0);
      ListNode p = l1, q = l2, curr = dummy;
      // 进位默认为 0
      int carry = 0;
      // 进入循环,以p和q两个链表指针都走到头为结束
      while (p != null || q != null) {
        int x = (p != null) ? p.val : 0;
        int y = (q != null) ? q.val : 0;
        // 进位参与运算
        int sum = carry + x + y;
        // 计算进位
        carry = sum / 10;
        // 构造新的结点存储计算后的位数数值
        curr.next = new ListNode(sum % 10);
        curr = curr.next;
        if (p != null) 
          p = p.next;
        if (q != null) 
          q = q.next;
      }
      // 处理数字最高位末尾进位情况
      if (carry > 0) {
        curr.next = new ListNode(carry);
      }
      return dummy.next;
    }
    

    这里用 p 和 q 分别存储了 l1 和 l2 两个链表的结点,以此为循环依据。循环跳出的条件为两个链表都走到了末尾。

    每一次循环中,处理每一位结点数数值并加上进位 carry 的值,运算后将数值取余存入新的结点,并将新的进位数存入 carry 进行存储。

    最后需要注意,当两个链表都处理完成之后,还需要判断最高位是否需要进位(carry > 0)。如果需要,创建一个新的链表结点存储进位值。

    这道利用链表做加法运算的题,就讲解到这里,但是它还有一些变种题。

    假如链表不是逆序按位存储数字呢?如果是正序存储。

    例如:

    1 → 2 → 3

    +3 → 2 → 1

    => 123 + 321 = ?

    那么如何计算呢?

    本文对你有帮助吗?留言、转发、收藏是最大的支持,谢谢!


    公众号后台回复成长『成长』,将会得到我准备的学习资料。

  • 相关阅读:
    HDU 4472 Count DP题
    HDU 1878 欧拉回路 图论
    CSUST 1503 ZZ买衣服
    HDU 2085 核反应堆
    HDU 1029 Ignatius and the Princess IV
    UVa 11462 Age Sort
    UVa 11384
    UVa 11210
    LA 3401
    解决学一会儿累了的问题
  • 原文地址:https://www.cnblogs.com/plokmju/p/linked_add.html
Copyright © 2011-2022 走看看