• 图解算法:单向链表做加法运算


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

    例如: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 = ?

    那么如何计算呢?

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


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

  • 相关阅读:
    关于推荐的一个算法工程师访谈,有一些内容值得看看
    Element.Event
    复数输出
    Passenger/Nginx/Debian快速部署Rails
    POJ3678【错误总会让自己有收获的】
    android在其他线程中访问UI线程的方法
    C++运算符重载的方法
    Struts2图片文件上传,判断图片格式和图片大小
    list view Item 里面有ImageButton
    用python实现远程复制 (scp + expect )
  • 原文地址:https://www.cnblogs.com/plokmju/p/linked_add.html
Copyright © 2020-2023  润新知