Leetcode - Add Two Numbers

**
Question:

You are given two linked lists representing two non-negative numbers. 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.

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

My code:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        if (l1 == null && l2 == null)
            return null;
        if (l1 == null)
            return l2;
        if (l2 == null)
            return l1;
        int carry = 0;
        int digit = 0;
        int val1 = l1.val;;
        int val2 = l2.val;;
        int sum = val1 + val2 + carry;
        digit = sum % 10;
        carry = sum / 10;
        ListNode temp = new ListNode(digit);
        ListNode head = temp;

        val1 = 0;
        val2 = 0;
        l1 = l1.next;
        l2 = l2.next;
        while (l1 != null || l2 != null) {
            if (l1 != null) {
                val1 = l1.val;
                l1 = l1.next;
            }
            if (l2 != null) {
                val2 = l2.val;
                l2 = l2.next;
            }
            sum = val1 + val2 + carry;
            digit = sum % 10;
            carry = sum / 10;
            temp.next = new ListNode(digit);
            temp = temp.next;
            val1 = 0;
            val2 = 0;
        }
        if (carry != 0) {
            temp.next = new ListNode(carry);
            temp = temp.next;
        }
            
        return head;
    }
    
    public static void main(String[] args) {
        Solution test = new Solution();
        ListNode n1 = new ListNode(1);
        ListNode n2 = new ListNode(9);
        ListNode n3 = new ListNode(9);
        ListNode n4 = new ListNode(9);
        ListNode n5 = new ListNode(9);
        ListNode n6 = new ListNode(9);
        ListNode n7 = new ListNode(9);
        ListNode n8 = new ListNode(9);
        ListNode n9 = new ListNode(9);
        ListNode n10 = new ListNode(9);

        n1.next = n2;
        n2.next = n3;
        n3.next = n4;
        n4.next = n5;
        n5.next = n6;
        n6.next = n7;
        n7.next = n8;
        n8.next = n9;
        n9.next = n10;
        n10.next = null;
        
        ListNode l1 = new ListNode(9);
        ListNode result = test.addTwoNumbers(l1, n1);
        while (result != null) {
            System.out.print(result.val);
            result = result.next;
        }
    }
}

My test result:

《Leetcode - Add Two Numbers》 Paste_Image.png

这次题目,额。不难。但我的确想错思路了。所以十分钟写好了代码,花了一个小时也没有测试通过。因为我的思路,本质是错误的。
我的思路是,将第一个链表的值一个个取出来,拼成字符串,再转换为整型。第二个也如此。再把他们加起来。然后再转换会链表形式。
这其中有个问题。
当两个链表取出来的数字都特别大,
JAVA int 是32bit, 范围大概从负的二十几亿到正的二十几亿。如果超出了这个范围,Integer.parseInt()这个方法就不能再使用了。我当时在想,怎么才能解决这个问题呢。我觉得这是语法的问题。我就去寻找新的方法。但没找到。其实这不是语法问题。即使有个方法可以解决int越界。用long来接收。如果数据再次超过了long的范围怎么办?没有一劳永逸的方法来解决这个问题。
于是,我只能去看了discuss。换了一种思路。更简单的思路。
实现一个简单的加法器。
最低位先相加,得到其输出以及进位。
然后将进位和两个链表的之后一位,一共三个数,一起相加。
以此类推。
然后问题就解决了。
主要还是思录错了吧。
附上我一开始写的转换字符串的代码。

public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        if (l1 == null && l2 == null)
            return null;
        if (l1 == null)
            return l2;
        if (l2 == null)
            return l1;
        // get the integer in list1
        int num1 = 0;
        String numStr1 = "";
        while (l1 != null) {
            numStr1 = Integer.toString(l1.val) + numStr1;
            l1 = l1.next;
        }
        if (numStr1.length() >= "2147483647".length() && numStr1.compareTo("2147483647") > 0)
            return null;
        num1 = Integer.parseInt(numStr1);
        // get the integer in list2
        int num2 = 0;
        String numStr2 = "";
        while (l2 != null) {
            numStr2 = Integer.toString(l2.val) + numStr2;
            l2 = l2.next;
        }
        if (numStr2.length() >= "2147483647".length() && numStr2.compareTo("2147483647") > 0)
            return null;
        num2 = Integer.parseInt(numStr2);
        // return the sum
        int sum = num1 + num2;
        int digit = 0;
        ListNode temp = new ListNode(sum % 10);
        ListNode head = temp;
        sum = sum / 10;
        while (sum != 0) {
            digit = sum % 10;
            temp.next = new ListNode(digit);
            temp = temp.next;
            sum = sum / 10;
        }
        
        return head;
    }
}

**
总结:
Java int 32 bit,当心越界。不是所有的数字 Integer.parseInt 都可以处理的。
简单的加法器。
**

之前说好的一天一道题目,打断了。
回国倒计时一个月了。哦,不,是二十天。
第一,为什么回国前的最后这一个月这么难熬。
第二,时间过得好快。
五月初的时候差点和女朋友分手。自己的精神受到了很大的打击。身体也受到了很大的打击。
这是我停止刷题的最本质原因。没有任何借口。在那之前,我的各方面状态都很好。
闹分手的时候,我当时觉得自己什么都不要了,什么都没有了。
整个人很颓废。很害怕。然后放弃了一切。就窝在汗臭味极其严重的被窝里,不知道干什么。
后来还是和好了。我也在想,以后去了美国,如果又发生激烈的冲突。我在这么颓废一段时间,我的人生轨迹应该会受很大影响吧。毕竟去了美国就要开始找工作了,然后一切真的会很忙很忙。
只不过这次的确伤的够深,下次再来下,可能不会再有这次这么痛了。
分手果然不是一次就能分的掉的。但是一次次分手之后复合,这段关系在本质上,正朝着分手的方向走。
我还是不想分手的。我想她也是。
我不能保证以后我们会在一起,那太幼稚了。
我只能保证,现在的我,想和她以后在一起。

忙完了这段事,紧接着家里爸妈发生了十分激烈的争吵。然后正逢我考试,但我妈找不到倾诉的对象,只有她的儿子可以倾诉。我也明白。她需要人安慰,理解。
于是我一般复习着知识点,做着题目,一边还得安慰她。
我的确越来越明白一个男人,到底该长什么样了。
男人可以承担一切责任,一切委屈,而不吭一声。然后,继续向前。
Because we are a man.
然后,家里的事逐渐平息,结果今天又有一件不开心的事发生了。
路上走的挺好的,一个白人就过来嘲讽我们中国人。
这是我在国外第一次碰到这种情况。
我没听懂他说什么,但是,那种语气,一定是极其恶意的。我无法忘记。
他骑着车。
他没想到我会回头。我回头,问了句, pardon。
他回了句, parden?
嘲讽我的英语。
然后开始说屁话。我已经明显感受到了他的恶意。所以也严肃了起来。
他也知道可能要开打了。开始叫他的朋友过来,准备一起打。
我心里其实是怕的。
我不是怕打不过他们。或者被他们打。
我怕的是,在英国这么一块极其排外,尤其排斥中国人的国家,我打了,去了警察局,警察一定会帮他们,而且他们还会说,我口语不行,对法律也不了解。而且,一天后又要考试了。如果因为这件事错过了考试,我的毕业证将拿不到。我的美国之行也将作废。
太多的顾虑。
中国人的传统想法就出来了。
多一事不如少一事。和这些没文化的人,没必要较真。
正好同伴也拉我,我就回头继续走了。然后我能听到背后,那人在说着,
Fuck you.

这一切都好像电影里演的那样,但的确就这么真实的发生了。
我和一个朋友说了这件事,他说,还是大部分中国人太懦弱了,总觉得多一事不如少一事,就这么忍过去了。然后老外就觉得中国人好欺负。
在我看来,不是这样的。
我不知道怎么,英国这个国家,对于中国,以及中国文化,就有一种很大的误解。
我去过曼彻斯特,去过伦敦。去过那里的唐人街。唐人街都有一块匾,上面写着唐人街。
结果这些地方的唐人街牌匾,无疑不是用紫光照着的。
晚上的时候过去,看着紫光下的唐人街,就感觉这块地方是吸鸦片嫖娼的地方。很暧昧,很软弱。
中国早就不是那样的中国了。
所以,虽然每年大量的留学生出国读书,但中国文化并没有很好地传送进入欧美国家。甚至基本没有进步。
我们必须得重视文化的传输,这样才能从根本上改变老外对中国人的看法。当然,总会有一些极端分子,就是仇视中国。
其次,我们要扬国威。
英国人为什么对日本人毕恭毕敬。除了这个国家强大的经济能力和素质。也有历史的原因。
二十世纪初的时候欧美国家是看不上亚洲国家的。结果日本接连战胜了中国,俄罗斯,在越南缅甸又把英国打的打败,屠杀英国军人,美国军人。
首先,站在道德高度,日本军人是错的。
但是,站在一个客观的角度,的确通过这种最极端的方式,快速的根正了欧美人对日本人的看法,知道他们不好惹。这就好比小孩打架。可能你一直瞧不起一个小孩,哪一天,突然被他狠狠揍了一顿,你还敢看不起吗?
文化传输来改变老外对中国的印象,是慢速的,和平的,健康的方式。
战争来改变老外对中国的印象,是快速的,非和平的,恶劣的方式,但往往更有效果。
人总是贱的,总是服比他强壮的人。
弱肉强食,在哪里都改变不了。
再过二十年,我想中国一定可以达到这么一个高度,不怒自威。
希望祖国更加强大!

Anyway, Good luck, Richardo!

My code:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        if (l1 == null)
            return l2;
        else if (l2 == null)
            return l1;
        ListNode dummy = new ListNode(-1);
        ListNode pre = dummy;
        int carry = 0;
        while (l1 != null && l2 != null) {
            int sum = l1.val + l2.val + carry;
            carry = sum / 10;
            ListNode curr = new ListNode(sum % 10);
            pre.next = curr;
            pre = curr;
            l1 = l1.next;
            l2 = l2.next;
        }
        if (l2 != null) { // add carry to l2
            while (l2 != null) {
                int sum = l2.val + carry;
                carry = sum / 10;
                ListNode curr = new ListNode(sum % 10);
                pre.next = curr;
                pre = curr;
                l2 = l2.next;
            }
        }
        else if (l1 != null) {
             while (l1 != null) {
                int sum = l1.val + carry;
                carry = sum / 10;
                ListNode curr = new ListNode(sum % 10);
                pre.next = curr;
                pre = curr;
                l1 = l1.next;
            }
        }
        
        if (carry != 0) {
            pre.next = new ListNode(carry);
        }
        return dummy.next;
    }
}

自己写了出来,但是错了几次。错在哪里?
1.当 l1, l2 都为null时,不代表结果已经出来了。 carry可以单独形成一个结点。
2.当l1 先为null,l2再为null,不代表结果已经出来了。 carry仍然可以单独形成一个结点。

看了下之前的做法。while (l1 != null || l2 != null) {…}
的确要比我的代码简单一些。

Anyway, Good luck, Richardo!

My code:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        if (l1 == null || l2 == null) {
            return (l1 == null ? l2 : l1);
        }
        
        ListNode p1 = l1;
        ListNode p2 = l2;
        int carry = 0;
        ListNode dummy = new ListNode(-1);
        ListNode curr = dummy;
        while (p1 != null || p2 != null) {
            if (p1 == null) {
                int sum = carry + p2.val;
                carry = sum / 10;
                sum = sum % 10;
                curr.next = new ListNode(sum);
                curr = curr.next;
                p2 = p2.next;
            }
            else if (p2 == null) {
                int sum = carry + p1.val;
                carry = sum / 10;
                sum = sum % 10;
                curr.next = new ListNode(sum);
                curr = curr.next;
                p1 = p1.next;
            }
            else {
                int sum = carry + p1.val + p2.val;
                carry = sum / 10;
                sum = sum % 10;
                curr.next = new ListNode(sum);
                curr = curr.next;
                p1 = p1.next;
                p2 = p2.next;
            }
        }
        
        if (carry != 0) {
            curr.next = new ListNode(carry);
        }
        
        return dummy.next;
    }
}

需要注意的一个地方就是,即使p1, p2 都是null了,但是,如果carry != 0, 仍需要多加一个结点。

Anyway, Good luck, Richardo! — 08/16/2016

    原文作者:Richardo92
    原文地址: https://www.jianshu.com/p/37d4945d5e61#comments
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞