2.两数相加
题目:
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
我的答案:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode result = new ListNode(0);
ListNode ln1=l1,ln2=l2,result_bk=result;
int op1,op2,carry=0;
while (ln1!=null || ln2!=null || carry!=0){
//同一位数的值相加
op1 = (ln1!=null)?ln1.val:0;
op2 = (ln2!=null)?ln2.val:0;
int sum = op1+op2+carry;
//如果计算结果是两位数,记住进位,在下一次进行添加
carry = sum/10;
//如果计算结果是两位数,只保留个位
sum = sum%10;
//存值
result.next = new ListNode(sum);
//结果链表节点后移,为下一次运算做准备
result = result.next;
//参数链表节点后移,为下一次运算做准备
if(ln1!=null) ln1 = ln1.next;
if(ln2!=null) ln2 = ln2.next;
}
return result_bk.next;
}
}
学习:
- 我的答案:没太看得懂题目,参考了官方答案。
- 分析题目:需要考虑可能情况有“两个链表元素位数不等”、“相加进位”、“链表赋值和节点移动”、“保存结果的初始节点地址”。
- 解决:
- 两个链表元素位数不等:在获取节点当前值的前判空,为了保证一个节点有值,一个节点为null,为null的节点赋值0,保证计算的顺利进行。
- 相加进位:注意一种情况:l1和l2都只有一个元素,且需要进位,这时一定要保证进位成功。两种方法:一是将进位与否作为是否继续运算的条件,二是在循环之外额外处理一次进位。
- 节点赋值和移动:ListNode是节点,该类只有构造函数,元素只有当存储当前值val和可存放指向下一个节点地址的ListNode,因此ListNode无法重复赋值。于是节点赋值只能靠将值存放在一个新节点里,然后将当前节点和新节点连接;节点移动只能通过将当前节点的地址改为指向下一个节点,然后获取这个新节点的值。
- 保存初始节点:定义一个节点result,用这个节点去操作,因为这个节点在计算的过程中不断后移,因此留一个备份result_bk,保存result节点的初始位置,最终返回的时候就可以通过备份节点result_bk获取初始节点的位置,进而获取有效结果的起始位置(result_bk.next 因为第一个数字0无效)。
总结:需要用到上一次结果的循环计算,注意未下一次的计算做好准备,注意变量是在循环内初始化(每一次都清空)还是在循环外初始化。