Solutin
递归
class Solution {
int flag = 0;
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
return calcNext(l1, l2);
}
private ListNode calcNext(ListNode l1, ListNode l2) {
if (l1 == null) {
return singleNext(l2);
}
if (l2 == null) {
return singleNext(l1);
}
int var0 = l1.val + l2.val + flag;
flag = var0 / 10;
return new ListNode(var0 % 10, calcNext(l1.next, l2.next));
}
private ListNode singleNext(ListNode list) {
if (flag == 0) {
return list;
}
if (list == null) {
return new ListNode(flag, null);
}
int var0 = list.val + flag;
flag = var0 / 10;
return new ListNode(var0 % 10, singleNext(list.next));
}
}
循环
class Solution {
int flag = 0;
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
}
if (l2 == null) {
return l1;
}
ListNode root = new ListNode();
ListNode cursor = root;
while (l1 != null && l2 != null) {
int var0 = l1.val + l2.val + flag;
flag = var0 / 10;
cursor.next = new ListNode(var0 % 10);
cursor = cursor.next;
l1 = l1.next;
l2 = l2.next;
}
while (l1 != null) {
if (flag == 0) {
cursor.next = l1;
break;
}
int var0 = l1.val + flag;
flag = var0 / 10;
cursor.next = new ListNode(var0 % 10);
cursor = cursor.next;
l1 = l1.next;
}
while (l2 != null) {
if (flag == 0) {
cursor.next = l2;
break;
}
int var0 = l2.val + flag;
flag = var0 / 10;
cursor.next = new ListNode(var0 % 10);
cursor = cursor.next;
l2 = l2.next;
}
if (flag > 0) {
cursor.next = new ListNode(flag);
}
return root.next;
}
}
Attention
- 链表中节点元素为数值逆序排列
- 数值的精度可能非常非常大
- 链表的长度一般会不一样长,注意空指针异常
- 两个数值可能为均为0
Think
我有一个非常漂亮的想法,想着将两个数值分别从链表中转化出来,将计算后的结果再转化回去。然后天真的将这个想法付诸实践了,期间还碰到了均为0的特殊情况,这个坑让我更加觉得,自己正在逼近正确的结果了。最后,大数给我上了一课,我还不死心的尝试用long类型来扩大变量的取值范围,特别佩服自己这种撞碎南墙不回头的不要脸的精神。
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int var1 = convertInt(l1);
int var2 = convertInt(l2);
int var3 = var1 +var2 ;
if (var3 == 0){
return new ListNode(0);
}else{
return (convertList(var3));
}
}
int convertInt(ListNode list) {
int var0 = list.val;
ListNode next = list.next;
for (int i = 1; next != null; i++) {
var0 += next.val * Math.pow(10, i);
next = next.next;
}
return var0;
}
ListNode convertList(int var0) {
if (var0 / 10 == 0 && var0%10 ==0) {
return null;
}
return new ListNode(var0 % 10, convertList(var0 / 10));
}
}
- 甭说long,就算BigInteger也扛不住
其实想到了可能会碰到数值精度的问题,只是 non-negative integers 这个描述给了我莫名的信心,然后就开始作死的尝试 。最开始是有两个思路的,另一种是创建一个进位变量,只是脑子闪过那种实现方式还要去标记,就下意识延后尝试了。后面发现简单的路被堵的死死的,只能考虑刚才避过去的那条路了(真是很成功的避过了正确答案)。
琢磨着应该用递归会快一点,空指针异常告诉了我,很有可能会有一个链表,先遍历完成。我就尝试了去判断两个链表的长度,然后在递归函数中判断较短的链表是否为空,为空就用另一个递归函数去处理单一的链表与进位变量。这时候,进位变量被我提升为了成员变量。优化过程中,发现好像直接在递归函数中分别判断两个链表是否为空会更好一些,于是就把判断长度的过程也给省了。
可以递归操作的,一般也都可以用循环来实现。这里的精髓是游标,就像小时候用小霸王玩的贪吃蛇一样,吃下去一个,就长长一点,被吃下去的,变成最新的那一点。要说有区别的话,就是链表是从尾部追加,每次在游标的尾巴上追加一个,然后让游标重新指向尾巴上的最后一个。
Others
- int类型的取值在哪个区间范围,long类型,BigInteger呢?
- java的引用调用跟指针之间的关系?
- 链表、单向链表、双向链表、循环链表、静态链表、头插法、尾插法、根节点、尾结点、游标的定义?
- 加法器的实现原理?
- 链表与顺序表的差异体现在哪里?
- 从调用方式的角度来看,可以怎样划分递归的类型?