LeetCode 2:Add Two Numbers

原题:

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Example

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.

 

给出的类和方法参数

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            }
}

 

大致意思就是输入两个链表,每个链表里node的值分别是两个数字的倒序排列,最终输出同样用链表输出两个数字和的倒序排列

先完成一个版本

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int num1, num2, num0;
ListNode l = null;

if (l1 != null && l2 != null &&
l1.next != null && l2.next != null &&
l1.next.next != null && l2.next.next != null) {
num1 = l1.val + l1.next.val * 10 + l1.next.next.val * 100;
num2 = l2.val + l2.next.val * 10 + l2.next.next.val * 100;
num0 = num1 + num2;
l = new ListNode(num0 % 10);
l.next = new ListNode((num0 / 10) % 10);
l.next.next = new ListNode(num0 / 100);
}
return l;
}
}

显然中间的if以及链表的遍历太恶心了,而且根本就不满足题目要求,因为根本没说是百位数,而且位数可以不一样,因此对于应该采用正常链表的遍历方法,分别获取数字,求和之后倒序写入链表返回,重新写下

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int num1 = 0, num2 = 0, num0;
int i = 0;
while (l1 != null) {
num1 += l1.val * Math.pow(10, i);
i++;
l1 = l1.next;
}
int j = 0;
while (l2 != null) {
num2 += l2.val * Math.pow(10, j);
j++;
l2 = l2.next;
}
num0 = num1 + num2;

ListNode l = null;
l = new ListNode(num0 % 10);
l.next = new ListNode((num0 / 10) % 10);
l.next.next = new ListNode(num0 / 100);
return l;
}
}

提交之后,报了一个错误

9 / 1562 test cases passed.
Status: Wrong Answer
Submitted: 0 minutes ago
Input:
[0]
[0]
Output:
[0,0,0]
Expected:
[0]

这里不满足的case为输入两个0,那就加一个判断,如果和为0,就返回0

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int num1 = 0, num2 = 0, num0;
int i = 0;
while (l1 != null) {
num1 += l1.val * Math.pow(10, i);
i++;
l1 = l1.next;
}
int j = 0;
while (l2 != null) {
num2 += l2.val * Math.pow(10, j);
j++;
l2 = l2.next;
}
num0 = num1 + num2;

ListNode l = null;
if (num0 == 0) {
l = new ListNode(0);
} else {
l = new ListNode(num0 % 10);
l.next = new ListNode((num0 / 10) % 10);
l.next.next = new ListNode(num0 / 100);
}
return l;
}
}

再次提交,还是错误

10 / 1562 test cases passed.
Status: Wrong Answer
Submitted: 0 minutes ago
Input:
[0]
[1]
Output:
[1,0,0]
Expected:
[1]

原来刚只将输入的数字的遍历方式改了,输出l对象还是当成三位数了,修改为链表添加值

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int num1 = 0, num2 = 0, num0;
int i = 0;
while (l1 != null) {
num1 += l1.val * Math.pow(10, i);
i++;
l1 = l1.next;
}
int j = 0;
while (l2 != null) {
num2 += l2.val * Math.pow(10, j);
j++;
l2 = l2.next;
}
num0 = num1 + num2;

ListNode l = new ListNode(0);
ListNode head = l;
while (num0 != 0) {
l.val = num0 % 10;
num0 /= 10;
if (num0 != 0) {
l.next = new ListNode(0);
l = l.next;
} else {
l.next = null;
}
}
return head;
}
}

还是错误

787 / 1562 test cases passed.
Status: Wrong Answer
Submitted: 0 minutes ago
Input:
[9]
[1,9,9,9,9,9,9,9,9,9]
Output:
[0,-4,-6,-3,-8,-4,-7,-4,-1,-2]
Expected:
[0,0,0,0,0,0,0,0,0,0,1]

仔细看看,输出的结果显示是越界了,原因是程序输入的是链表,存储的是倒序的数字,我这里的处理方法是,先把每个数字正序过来,求和,然后再倒序输出,这样就会出现一种错误场景,正序的数字有可能越界,而倒序的数字没有越界,这样不影响程序输入和输出,因为输入输出是链表,因此问题还在于程序实现的方法不行

本来是不想计较两个数字位数不一致,所以直接计算和,倒序,如此看来还是得每一位求和,然后写入链表

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode l = new ListNode(0);
ListNode head = l;
int sum = 0, tmp = 0;
//l1 : 9 9
//l2 : 1 9 9 9
//l.next : 0 9 0 0 1
while (l1 != null && l2 != null) {
sum = l1.val + l2.val + tmp;
l.next = new ListNode(sum % 10);
tmp = sum / 10;
l = l.next;
l1 = l1.next;
l2 = l2.next;
}

while (l2 != null) {
sum = l2.val + tmp;
l.next = new ListNode(sum % 10);
tmp = sum / 10;
l = l.next;
l2 = l2.next;
}

while (l1 != null) {
sum =l1.val + tmp;
l.next = new ListNode(sum % 10);
tmp = sum / 10;
l = l.next;
l1 = l1.next;
}

if (tmp == 1) {
l.next = new ListNode(tmp);
}

return head.next;
}
}

提交验证无误

Submission Detail
1562 / 1562 test cases passed.
Status: Accepted
Runtime: 69 ms
Submitted: 0 minutes ago

每一对相同位置的数字求和,从l.next开始写,sum % 10为当前位置做和的值,sum / 10决定是否要前一位+1

当位数少的那个数遍历完了,就剩下位数多的那个数,照葫芦画票,摩10的值写入链表,除10的商0或者1都加到高位(倒序的next)

当位数多的这个数遍历完了,while循环就退出了,但是sum是否要进位还不知道,因此最后还要判断一下,如果满10了,高位的1还要写入新的链表值里

最后因为是从l.next开始写的,因此遍历head也要从next开始

有人给出了递归的写法

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
if (l1 == null || l2 == null) {
return l1 == null ? l2 : l1;
}
int value = l1.val + l2.val;
ListNode result = new ListNode(value % 10);
result.next = addTwoNumbers(l1.next, l2.next);
if (value >= 10) {
result.next = addTwoNumbers(new ListNode(value / 10), result.next);
}
return result;
}
}

 

发表评论