前言
本文主要介绍如何将两个链表每个节点按数值相加形成新链表。
需求描述
给出两个链表的头结点head1和head2,每个节点的值都为0~9,每个链表的节点从左到右认为是某个数字的从低位到高位的值,然后相加后,返回相加后的链表。
示例:
链表1为:6->9->3->1 ,链表2为 4->5->3,相加后的节点为 0->5->7->1。
用数值理解为:1396+354=1750。
思路分析
这个题目咋一看很简单,不就是把两个链表反转相加吗?这有什么难度?
说的也对,题目很简单,主要是怎么实现,另外需要注意的是相加有进位信息,下面来一起分析一下。
这个题目需要先找到长链表和短链表,所以需要实现一个获取链表长度的函数,获取链表长度就比较简单了,从头结点一步一下往后找即可。
获取到链表长度后,循环判断时,有3种情况需要考虑判断:
- 长链表和短链表都有节点,如遍历链表1的
1、2、3节点和链表2的4、5、3节点的时候。 - 长链表还有节点,短链表节点已经遍历完,如遍历链表1的
6节点时,此时链表2已经没有可用节点了。 - 长链表和短链表都已经遍历完,两个链表的节点都已经遍历了一遍。
因为有进位信息,所以我们需要一个额外变量用来记录进位信息,下面用示例的节点来分析一下计算过程:
-
第一种情况:
-
第
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。
- 第4次相加,
-
第三种情况:
- 没有节点了,也没有进位信息,直接返回结果
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种情况来考虑,总体来说本次题目相对还是比较简单的。