Algorithm之路二:Add Two Numbers

来源:互联网 发布:plsql编程入门 编辑:程序博客网 时间:2024/06/05 18:38

题目:

给出两个非空链表,两个非空链表的节点个数不一定相同,每一个节点都包含一个整数值(范围是0-9),且只有这唯一一个整数值,整个链表存储着一个多位数的逆序,例如2->3->1代表123,6->4->7代表着746,现在给出两个链表计算这两个链表所代表的的多位数之和,并且将和以链表的形式输出。


解:

从两个链表的头部开始,将对应位置的数值相加并加上进位变量carry,将进位保留在变量carry中。

例如出现3295+132这样的状况时,5+2=7,carry=0,9+3=12,carry = 1,2+1+1=4,carry=0,3+0+0=3,则得到的结果为7->2->4->3。

在java中的对象实体和指向对象的指针不做区分,可以直接把对象实体当做指针使用,这对于一直使用C++或者C的我来说感觉有点别扭。

为了节省空间,则将计算的结果都保留在两条给出的链表中的一条中,这样就几乎不需要额外的空间,如果不考虑题目给出的链表空间,那么该算法的空间复杂度仅为O(1)。

public class Add_Two_Number {public static class ListNode {int val;//链表节点的值ListNode next;//java中没有指针ListNode(int x)//构造函数{val = x;}}public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode temp = l2,temp1 = temp;int carry = 0;while( temp != null||l1 != null){if(temp != null&&l1 != null)temp.val += l1.val + carry;if(l1 == null)temp.val += carry;if(temp == null){temp1.next = new ListNode(l1.val+carry);temp = temp1.next;}carry = 0;if(temp.val >= 10){carry = 1;temp.val %= 10;}if(l1 != null)l1 = l1.next;if(temp != null){temp1 = temp;temp = temp.next;}}if(carry == 1)temp1.next = new ListNode(1);return l2;    }public static void main(String[] args) {// TODO Auto-generated method stubListNode l1 = new ListNode(2);//测试l1.next = new ListNode(4);l1.next.next = new ListNode(3);l1.next.next.next = new ListNode(5);ListNode l2 = new ListNode(5);l2.next = new ListNode(6);l2.next.next = new ListNode(4);ListNode consequence = addTwoNumbers(l1,l2);while(consequence != null){System.out.println(consequence.val);consequence = consequence.next;}}}

此方法的时间复杂度为O(max(m,n)。因为数值相加的次数为max(m,n)。

空间复杂度O(1)。

碰到的智障问题:

在第24行,不能直接写成temp = new ListNode(l1.val+carry);,因为此时temp只是为遍历整个l2定义的一个临时的指针,不存在与l2的链表之内,有着自己的一个空间,在上一个迭代中,temp1 = temp,temp = temp.next,在此次迭代中temp = null,为了给l2尾部添加一个新空间,如果直接temp = new ListNode(l1.val+carry);,那么这个新申请的节点将和l2链分离,故应该temp1.next = newListNode(l1.val+carry)。

原创粉丝点击