本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接
题目描述
两数相加
给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 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, 100]内 0 <= Node.val <= 9- 题目数据保证列表表示的数字不含前导零
思路分析
题目其实并不难,我们可以先把两个链表的数据存到两个 ArrayList中,然后再依次相加,同时也要注意超过 10 进 1。关键在于细心严谨。
代码展示
双指针解法,时间复杂度是,空间复杂度是。
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//先判断哪个比较长
boolean l1IsLonger = false;
List<Integer> firList = new ArrayList<>();
List<Integer> secList = new ArrayList<>();
while (l1 != null) {
firList.add(l1.val);
l1 = l1.next;
}
while (l2 != null) {
secList.add(l2.val);
l2 = l2.next;
}
ListNode finalNode = new ListNode();
ListNode newHead = finalNode;
boolean needPlus = false;
if (firList.size() > secList.size()) {
int secLength = secList.size(); //4
int j = 0; //6
for (int i = 0; i < secLength; i++) {
int val = firList.get(j) + secList.get(i) + (needPlus ? 1 : 0);
if (val >= 10) {
needPlus = true;
} else {
needPlus = false;
}
newHead.next = new ListNode(needPlus ? (val - 10) : val);
newHead = newHead.next;
j++;
}
for (int i = j; i < firList.size(); i++) {
int val = firList.get(i) + (needPlus ? 1 : 0);
if (val >= 10) {
needPlus = true;
} else {
needPlus = false;
}
newHead.next = new ListNode(needPlus ? (val - 10): val);
newHead = newHead.next;
}
} else {
int firLength = firList.size();
int j = 0;
for (int i = 0; i < firLength; i++) {
int val = firList.get(i) + secList.get(j) + (needPlus ? 1 : 0);
if (val >= 10) {
needPlus = true;
} else {
needPlus = false;
}
newHead.next = new ListNode(needPlus ? (val - 10) : val);
newHead = newHead.next;
j++;
}
for (int i = j; i < secList.size(); i++) {
int val = secList.get(i) + (needPlus ? 1 : 0);
if (val >= 10) {
needPlus = true;
} else {
needPlus = false;
}
newHead.next = new ListNode(needPlus ? (val - 10): val);
newHead = newHead.next;
}
}
if (needPlus){
newHead.next = new ListNode(1);
}
return finalNode.next;
}
当然也可以进一步优化,把 空间复杂度将为,解法如下:
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head = null, tail = null;
int carry = 0;
while (l1 != null || l2 != null) {
int n1 = l1 != null ? l1.val : 0;
int n2 = l2 != null ? l2.val : 0;
int sum = n1 + n2 + carry;
if (head == null) {
head = tail = new ListNode(sum % 10);
} else {
tail.next = new ListNode(sum % 10);
tail = tail.next;
}
carry = sum / 10;
if (l1 != null) {
l1 = l1.next;
}
if (l2 != null) {
l2 = l2.next;
}
}
if (carry > 0) {
tail.next = new ListNode(carry);
}
return head;
}
总结
这样看到题目很容易就能想到解法主要是考察开发者的编程能力,是否足够严谨细心。