給出兩個非空
的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照逆序
的方式存儲的,而且它們的每一個節點只能存儲一位
數字。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
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
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
了。
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; } }
嗯,這下就沒什麼問題了。😜
若是你有更好的解法,歡迎留言討論~