描述
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
提示:
- 每个链表中的节点数在范围
[1, 100]
内 0 <= Node.val <= 9
- 题目数据保证列表表示的数字不含前导零
示例
示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4] 输出:[7,0,8] 解释:342 + 465 = 807.
示例 2:
输入:l1 = [0], l2 = [0] 输出:[0]
示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9] 输出:[8,9,9,9,0,0,0,1]
算法思路1
我快碎了,这个示例会有特别大的链表,所以我这样写根本不会得到精确的结果的(=_=)(但是我写了好半天,不能白写!!!贴到这里警示大家做提前一定看好输入范围在想思路啊!!!)看答案2吧,那个准确……
当然大家也可以借着这个看一下链表的一些基操以及数据结构定义。
答案1
import java.util.HashSet;
import java.util.*;
class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
public class Main {
public static void main(String[] args) {
ListNode l1 = new ListNode(2);
l1.next = new ListNode(4);
l1.next.next = new ListNode(3);
ListNode l2 = new ListNode(5);
l2.next = new ListNode(6);
l2.next.next = new ListNode(4);
ListNode l3 = addTwoNumbers(l1, l2);
while (l3 != null) {
System.out.println(l3.val);
l3 = l3.next;
}
}
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
if (l1.val == 0&&l1.next==null) return l2;
if (l2.val == 0&&l2.next==null) return l1;
double a1 = 0;
double a2 = 0;
int count = 0;
while (l1 != null) {
double m = l1.val * (Math.pow(10, count));
a1 = a1 + m;
count++;
l1 = l1.next;
}
int count2 = 0;
while (l2 != null) {
double n = l2.val * Math.pow(10, count2);
a2 = a2 + n;
count2++;
l2 = l2.next;
}
double s = a1 + a2;
ListNode current = new ListNode(); // 创建虚拟头节点
ListNode l3 = current; // 当前节点指针
while (s >= 1) {
double t = s % 10;
current.next = new ListNode((int)t); // 构建新节点并连接到当前节点的下一个节点
current = current.next; // 移动当前节点指针到下一个节点
s = (s / 10);
}
return l3.next; // 返回结果链表的头节点
}
}
算法思路2
按位逐个加这两个数,就像纸上计算那样,同时要处理好两个数字相加产生的进位。以下是如何修改解决方案的步骤:
- 初始化一个结果链表的虚拟头节点。
- 初始化一个变量
carry
来跟踪进位。 - 遍历
l1
和l2
直到两者都到达末尾。 - 每一步循环中,计算当前位的和加上
carry
。 - 要添加到结果链表的新位是
sum % 10
。 - 更新
carry
为sum / 10
。 - 将
l1
、l2
和结果链表的指针向前移动。 - 循环结束后,检查是否有剩余的
carry
,如果有,则添加一个值为此carry
的新节点。 - 返回虚拟头节点的下一个节点,这就是结果链表的实际开始。
答案2
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(0);
ListNode p = l1, q = l2, curr = dummyHead;
int carry = 0;
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 dummyHead.next;
}
}
详解2
注意表达式这里处理非常好,可以避免遍历一个空之后跳出重开一个while循环。
int x = (p != null) ? p.val : 0;
int y = (q != null) ? q.val : 0;