如何将两个链表每个节点按数值相加形成新链表?

295 阅读3分钟

前言

本文主要介绍如何将两个链表每个节点按数值相加形成新链表。

需求描述

给出两个链表的头结点head1head2,每个节点的值都为0~9,每个链表的节点从左到右认为是某个数字的从低位到高位的值,然后相加后,返回相加后的链表。

示例: 链表1为:6->9->3->1 ,链表2为 4->5->3,相加后的节点为 0->5->7->1

用数值理解为:1396+354=1750

思路分析

这个题目咋一看很简单,不就是把两个链表反转相加吗?这有什么难度?

说的也对,题目很简单,主要是怎么实现,另外需要注意的是相加有进位信息,下面来一起分析一下。

这个题目需要先找到长链表和短链表,所以需要实现一个获取链表长度的函数,获取链表长度就比较简单了,从头结点一步一下往后找即可。

获取到链表长度后,循环判断时,有3种情况需要考虑判断:

  1. 长链表和短链表都有节点,如遍历链表1的1、2、3节点和链表2的4、5、3节点的时候。
  2. 长链表还有节点,短链表节点已经遍历完,如遍历链表1的6节点时,此时链表2已经没有可用节点了。
  3. 长链表和短链表都已经遍历完,两个链表的节点都已经遍历了一遍。

因为有进位信息,所以我们需要一个额外变量用来记录进位信息,下面用示例的节点来分析一下计算过程:

  • 第一种情况:

    • 1次相加6 + 4 = 10,得到的结果与10进行取模运算,如果取模结果为0,有进位信息记录进位为1,取值为0

    • 2次相加,9 + 5 + 1 = 15,与10取模为5,有进位信息,继续记录进行为1,取值为5

    • 3次相加,3 + 3 + 1 = 7,与10取模为0,无进位信息记录为0,取值为7

  • 第二种情况:

    • 第4次相加,1 + 0 = 1,与10取模为0,无进位信息记录为0,取值为1
  • 第三种情况:

    • 没有节点了,也没有进位信息,直接返回结果1750

需要注意的是,如果这时有进位信息的话,需要补充一个节点,节点值为1,并把这补充的节点拼接在较长的链表上。

代码实现

计算逻辑以及思路都已经介绍完了,根据上面的分析,下面来看一下代码是怎么实现的吧。

链表节点代码定义:

public class ListNode {
   public int val;
   public ListNode next;
}

再看下获取链表长度的代码,遍历链表并计数,这个比较简单,代码如下:

public int listLength(ListNode head) {
   int len = 0;
   while (head != null) {
      len++;
      head = head.next;
   }
   return len;
}

两个链表节点相加的代码实现,需要传进来两个头结点,具体代码如下:

public ListNode addTwoNumbers(ListNode head1, ListNode head2) {
   int len1 = listLength(head1);
   int len2 = listLength(head2);
   ListNode node1 = len1 >= len2 ? head1 : head2;
   ListNode node2 = node1 == head1 ? head2 : head1;
   ListNode longNode = node1;
   ListNode shortNode = node2;
   ListNode last = longNode;
   // 用来记录进位信息
   int temp = 0;
   int curNum = 0;
   // 第一种情况时
   while (shortNode != null) {
      curNum = longNode.val + shortNode.val + temp;
      longNode.val = (curNum % 10);
      temp = curNum / 10;
      last = longNode;
      longNode = longNode.next;
      shortNode = shortNode.next;
   }
   // 第二种情况时
   while (longNode != null) {
      curNum = longNode.val + temp;
      longNode.val = (curNum % 10);
      temp = curNum / 10;
      last = longNode;
      longNode = longNode.next;
   }
   // 第三种情况时
   if (temp != 0) {
      last.next = new ListNode(1);
   }
   return node1;
}

总结

本文主要介绍如何将两个链表每个节点按数值相加形成新链表,在本次实现时,并没有创建新的链表,而是在给出的链表基础上直接记录的,在计算的过程中,把计算逻辑需要分成3种情况来考虑,总体来说本次题目相对还是比较简单的。