两数向加
题目
给出两个 非空 的链表用来表示两个非负的整数。其中它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
- 示例:
none
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
分析
最开始按照题目要求我自己思考的想法是
第一步:先得到数字
第二步:数字相加
第三步:将和转化成ListNode的数据结构
递归数字解法
java
//client方法
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
BigInteger result = new BigInteger(buildNum(l1)).add(new BigInteger(buildNum(l2)));
return buildNote(result.toString());
}
/**
* 将链表转化成数字
*/
private static String buildNum(ListNode l1) {
if (l1.next != null) {
return buildNum(l1.next) + "" + l1.val;
} else {
return String.valueOf(l1.val);
}
}
/**
* 将数字转化成列表
**/
private static ListNode buildNote(String num) {
ListNode currentNode;
if (num.length() > 1) {
String i = num.substring(0, num.length() - 1);
currentNode = new ListNode(Integer.valueOf(num.substring(num.length() - 1)));
currentNode.next = buildNote(i);
} else {
currentNode = new ListNode(Integer.valueOf(num));
}
return currentNode;
}
- 实验结果
抛出BigInteger不能识别异常,应该是评测程序不能使用相关的引用类。就代表着不能使用数值之和的解法。
移位相加解法
- 代码
java
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//初始化一个新的链表
ListNode rsNote = new ListNode(0);
//初始化时将当前节点设置成为rsNode
ListNode currNode = rsNote;
ListNode pNode = l1;
ListNode qNode = l2;
//表示是否有进位
int carry = 0;
while(pNode !=null || qNode != null){
//当前循环中的node
int sum = (null!=pNode?pNode.val:0)+(null!=qNode?qNode.val:0)+carry;
//当前进位
carry = sum/10;
//构建出当前node节点
currNode.next = new ListNode(sum % 10);
//将下一次使用到的当前节点设置成为此次循环得到的的下一个节点
currNode = currNode.next;
//遍历列表中的下一个元素
pNode = null!=pNode?pNode.next:pNode;
qNode = null!=qNode?qNode.next:qNode;
}
//最后处理最后一个进位数值
if(carry > 0){
currNode.next = new ListNode(carry);
}
return rsNote.next;
}
这里使用到的数学原理就只是逢十进位。先设置一个标志位carry,然后计算当前位置的值模除10从而得到当前位置的值。
这里使用了一个技巧,在对这种尾节点进行递增时使用了
java
currNode.next=node;
currNode = currNode.next;
用图来表示

tkiMSU.png
不断的将当前节点顺着链表向下移动,并且给每一个next节点进行赋值。这种方法比递归所占用的空间较小。
总结:
两数向加问题本质上还是要去解决进位问题而不是进行数值计算,这种进位问题应该还可以继续进行优化。