美文网首页
LeetCode(2) ---- Add Two Numbers

LeetCode(2) ---- Add Two Numbers

作者: 做梦枯岛醒 | 来源:发表于2017-10-09 18:02 被阅读21次

上通信的课就跟室友一起刷题玩,结果读题目读了半天,好歹我也是过了四级的人啊,怎么能这样,干脆百度题目意思……

题目: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.

样例:Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8

翻译:给你两个链表,然后他们的反序是一个数字(正序2也就是个位,4是十位,3是百位,然后计算他们的俩的和,和输出也是反序,并且是一个链表形式

My View

我的想法是把链表表示的数先算出来,然后两者相加得出答案之后转换为链表,由于结果转化为链表的那部分出现了一点问题,最后也没搭理,几天过去了竟然不想再写,直接去solution了

solution

官方给的示意图:


Figure 1. Visualization of the addition of two numbers: 342 + 465 = 807.
Each node contains a single digit and the digits are stored in reverse order.
到这里可能已经很深刻的理解题目的意思了。
首先我们考虑单独相加的方法,从l1和l2的链表头开始,2+5 = 7,4+6 = 10,10的话就会有进位,作为carry(携带)送给高位,也就是3+4+1 = 8;
那么在这里carry只可能是0或者1,这是符合我们数学逻辑的。

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    //初始化头结点
    ListNode dummyHead = new ListNode(0);
    ListNode p = l1, q = l2, curr = dummyHead;
    int carry = 0;
    //进入链表循环
   while (p != null || q != null) {
       //记录每个节点的值
        int x = (p != null) ? p.val : 0;
        int y = (q != null) ? q.val : 0;
       //计算实际值(添加carry之后) 
        int sum = carry + x + y;
       //判断有没有进位
        carry = sum / 10;
       //添加去除carry位的值
        curr.next = new ListNode(sum % 10);
        //移动节点
        curr = curr.next;
        if (p != null) p = p.next;
        if (q != null) q = q.next;
    }
   //如果到循环结束了还余下一个carry = 1,那么就得新建一个高位,
   可以参考l1=[9,9] ,l2=[1] 这种情况
    if (carry > 0) {
        curr.next = new ListNode(carry);
    }
   //最后返回dummyHead的下一个节点,(因为第一个节点是0,,java很坑吧)
    return dummyHead.next;
}

上述算法的时间复杂和空间复杂都是O(max(m,n)),因为只有一层循环,
所以取决于链表最大长度。

正当试着提交这份代码的时候,系统竟然判定超时,不太理解系统给的方法竟然会超时……

然后去淘discuss,发现大部分人的方法是如下的:

  public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        //在定义地方和上面的一致
        ListNode c1 = l1;
        ListNode c2 = l2;
        ListNode sentinel = new ListNode(0);
        ListNode d = sentinel;
        int sum = 0;
       //循环也是一样的
        while (c1 != null || c2 != null) {
           //这里直接用sum来储存carry和node_sum值  
            sum /= 10;
            if (c1 != null) {
                sum += c1.val;
                c1 = c1.next;
            }
            if (c2 != null) {
                sum += c2.val;
                c2 = c2.next;
            }
            d.next = new ListNode(sum % 10);
            d = d.next;
        }
      //这里其实和方法一一样  
      if (sum / 10 == 1)
            d.next = new ListNode(1);
        return sentinel.next;
    }

着实看不懂他俩差别在哪,除了carry与sum合并为一个之外,有知道的宝宝么?

相关文章

网友评论

      本文标题:LeetCode(2) ---- Add Two Numbers

      本文链接:https://www.haomeiwen.com/subject/npavextx.html