【LeetCode】兩數相加

題目描述

給出兩個非空的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照逆序的方式存儲的,而且它們的每一個節點只能存儲一位數字。java

若是,咱們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。bash

您能夠假設除了數字0以外,這兩個數都不會以0開頭。ide

示例:3d

輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
緣由:342 + 465 = 807

題目解析

這個題目的意思看起來其實很簡單,提供了兩個鏈表,每一個鏈表表明一個非負整數,它們各自的位數是按照逆序方式存儲的,例如:(2 -> 4 -> 3)表明整數342(5 -> 6 -> 4)則表明整數465,兩數相加的結果天然是807,這就是咱們要給出的答案,可是要用鏈表的形式返回7 -> 0 -> 8。題目中說明了是非空鏈表,因此就不用考慮鏈表爲null的狀況了。code

乍眼一看,很簡單啊,不就是把兩個數相加嘛,我先把它整成整數,而後相加,最後把結果整成鏈表,完美,哈哈哈哈,簡直被本身的聰明才智給折服。blog

翻車嘗試1:蝦扯蛋法

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode head1 = l1;
        ListNode head2 = l2;
        int i = 0;
        int j = 0;
        int index = 0;
        // 將鏈表l1轉化爲整數
        while (head1 != null) {
            i += head1.val * Math.pow(10, index);
            index++;
            head1 = head1.next;
        }
        index = 0;
        // 將鏈表l2轉化爲整數
        while (head2 != null) {
            j += head2.val * Math.pow(10, index);
            index++;
            head2 = head2.next;
        }
        int sum = i + j;
        ListNode newHead = new ListNode(0);
        ListNode tmpHead = newHead;
        int sign = 0;
        // 將結果轉化爲鏈表
        while (sum > 0 || sign == 0) {
            int tmp = sum % 10;
            sum = sum / 10;
            tmpHead.next = new ListNode(tmp);
            tmpHead = tmpHead.next;
            sign++;
        }
        return newHead.next;
    }
}

簡直輕鬆加愉快,讓咱們來提交一下。leetcode

怎麼肥四,小老弟,翻車了啊。讓咱們看看錯誤緣由:get

輸入:
[9]
[1,9,9,9,9,9,9,9,9,9]
輸出:
[0]
預期:
[0,0,0,0,0,0,0,0,0,0,1]

看樣子應該是整數型溢出了。。。難不倒我,改爲long型不就完事了。io

翻車嘗試2:蝦扯蛋升級法

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode head1 = l1;
        ListNode head2 = l2;
        long i = 0;
        long j = 0;
        long index = 0;
        while (head1 != null) {
            i += head1.val * Math.pow(10, index);
            index++;
            head1 = head1.next;
        }
        index = 0;
        while (head2 != null) {
            j += head2.val * Math.pow(10, index);
            index++;
            head2 = head2.next;
        }
        long sum = i + j;
        ListNode newHead = new ListNode(0);
        ListNode tmpHead = newHead;
        int sign = 0;
        while (sum > 0 || sign == 0) {
            int tmp = (int)(sum % 10);
            sum = sum / 10;
            tmpHead.next = new ListNode(tmp);
            tmpHead = tmpHead.next;
            sign++;
        }
        return newHead.next;
    }
}

此次總沒事了吧,再提交一下:編譯

這個磨人的小妖精,整出個這麼大的數來折騰我,long型也溢出了。。。

逼我用絕招,是時候祭出個人BigInteger了。

翻車嘗試3:蝦扯蛋終極法

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode head1 = l1;
        ListNode head2 = l2;
        BigInteger i = new BigInteger(0);
        BigInteger j = new BigInteger(0);
        long index = 0;
        while (head1 != null) {
            i.add(BigInteger.valueOf(head1.val * Math.pow(10, index)));
            index++;
            head1 = head1.next;
        }
        index = 0;
        while (head2 != null) {
            j.add(BigInteger.valueOf(head2.val * Math.pow(10, index)));
            index++;
            head2 = head2.next;
        }
        BigInteger sum = i.add(j);
        ListNode newHead = new ListNode(0);
        ListNode tmpHead = newHead;
        int sign = 0;
        while (sum.compareTo(0) == 1 || sign == 0) {
            int tmp = sum.mod(10).intValue();
            sum = sum.divide(10);
            tmpHead.next = new ListNode(tmp);
            tmpHead = tmpHead.next;
            sign++;
        }
        return newHead.next;
    }
}

此次,連編譯都不經過了,emmmm,看來不許用BigInteger這個類。

常規解法

既然邪門歪道走不通,那就仍是用常規操做來解決吧,仔細想一想,其實也很簡單,咱們從兩個鏈表的頭節點開始,一塊兒遍歷,將相加獲得的結果存入新的鏈表中便可。

這裏須要注意的就是要考慮進位的狀況,好比:4 + 6 = 10,那麼在處理後一個節點3 + 4的時候,須要再加1,所以須要有一個進位標誌來表示是否須要進位。

另外,兩個鏈表的長度並不必定相等,須要考慮像上面那樣一個很長,一個很短,並且後續一直進位的狀況:

[9]
[1,9,9,9,9,9,9,9,9,9]

因此咱們能夠定義一個叫carry的變量來表示是否須要進位。

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode head1 = l1;
        ListNode head2 = l2;
        ListNode newHead = new ListNode(0);
        ListNode head3 = newHead;
        // 進位標誌
        boolean carry = false;
        while (head1 != null || head2 != null) {
            // 獲取對應位置的值而後相加
            int x = (head1 != null) ? head1.val : 0;
            int y = (head2 != null) ? head2.val : 0;
            int sum = carry ? (x + y + 1) : (x + y);
            // 處理進位
            if (sum >= 10){
                sum -= 10;
                carry = true;
            } else {
                carry = false;
            }
            // 新增節點
            head3.next = new ListNode(sum % 10);
            head3 = head3.next;
            if (head1 != null) head1 = head1.next;
            if (head2 != null) head2 = head2.next;
        }
        if (carry) {
            head3.next = new ListNode(1);
        }
        return newHead.next;
    }
}

嗯,這下就沒什麼問題了。😜

本題中文版連接

本題英文版連接

若是你有更好的解法,歡迎留言討論~

相關文章
相關標籤/搜索