給定兩個非空鏈表來表示兩個非負整數。位數按照逆序方式存儲,它們的每個節點只存儲單個數字。將兩數相加返回一個新的鏈表。
示例:
輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
原因:342 + 465 = 807
好吧,看到這道題就頭疼,這不就是C語言中的鏈表嗎?想當年,學了半學期C還是不是鏈表……好吧,慢慢琢磨怎麼使用單向鏈表。簡單學會怎麼使用單向鏈表後開始着手這道題。大致思路是:先將鏈表轉換成字符串形式,然後在轉換成整數,這可能會超過Int的範圍,所以應該用BigInteger。
import java.math.BigInteger;
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
BigInteger ans = new BigInteger(ListNode2String(l2)).add(new BigInteger(ListNode2String(l1)));
String answer = new StringBuilder(ans.toString()).reverse().toString();
ListNode start = new ListNode(0);
ListNode node = start;
for (int i = 0; i < answer.length(); i++) {
node.next = new ListNode(Integer.valueOf(answer.charAt(i) - 48));
node = node.next;
}
return start.next;
}
public String ListNode2String(ListNode node) {
String result = "";
while (node != null) {
result += Integer.toString(node.val);
node = node.next;
}
return new StringBuilder(result).reverse().toString();
}
}
簡單直接暴力
但是,這種暴力算法本身沒有直接使用單向鏈表本身的特性來計算,只是將運用BigInteger類計算得到的值放上去了而已。因爲若想要直接使用單向鏈表來計算,需考慮以下幾點:
- 兩鏈表對應的當前位的計算值是否大於10,若是,則需進位。
- 若其中一個鏈表較短,則需要將另一鏈表拷貝到結果中,同事考慮進位問題。
- 若最後一位還有進位,則還需要在末尾添加一個new ListNode(1)。
在該題的閱讀解答中,發現有大佬上傳了一份C++(至少不是Java和Python)的代碼:
class Solution {
public:
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {
ListNode preHead(0), *p = &preHead;
int carry = 0;
while (l1 || l2 || carry) {
int sum = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry;
carry = sum / 10;
p->next = new ListNode(sum % 10);
p = p->next;
l1 = l1 ? l1->next : l1;
l2 = l2 ? l2->next : l2;
}
return preHead.next;
};
其中
int sum = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry;
表示若當前鏈表位不爲空,則用當前位的值相加,否則用0相加,畢竟任何數加0等於本身,在加上進位可得到當前位的值。
l1 = l1 ? l1->next : l1;
表示若當前位不爲空,則指向鏈表中的下一位,否則指向當前位(即空)。
大循環只有當兩個鏈表當前位都爲空且沒有進位產生時才退出。
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode ans = new ListNode(0);
ListNode temp = ans;
boolean jinwei = false;
while (l1 != null || l2 != null ||jinwei) {
int sum = (l1 != null ? l1.val : 0) + (l2 != null ? l2.val : 0) + (jinwei ? 1 : 0);
jinwei = ((int) (sum / 10)) == 1 ? true : false;
temp.next = new ListNode(sum % 10);
temp = temp.next;
l1 = (l1!=null)?l1.next:l1;
l2 = (l2!=null)?l2.next:l2;
}
return ans.next;
}
}