終於,隔了很久之後,我又開始題了。
其實刷OJ是爲了保研機試提前做準備,也是爲了給自己的編程知識保溫,但是當我發現自己兩個月了還在刷easy難度的題目的時候,我知道,我得挑戰點真正的題目了。
還是先來看一下今天的題目
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
Explanation: 342 + 465 = 807.
注意這裏鏈表題目已經給你反向好了,做的時候直接從頭開始處理就好了,並且輸出的鏈表也是反向的,不用進行反向處理。
隔了這麼久做題,手感冰涼,愣是剛了一上午,沒弄出來2333,我的方法總是有個case過不了,無奈之下,去看了人家的算法,發現我之前的想法是真的土。
更好的算法
這是LeetCode上我寫的時候排名第一的算法,簡明扼要,驚爲天人。
算法的妙處在於設置了一個全局變量carry,存儲每次兩個鏈表節點相加的和,用第三個鏈表保存其對10取模的值,然後將其除以10更新,這樣就解決了進位的問題,最後只需要再判斷當前carry是不是1(進位導致carry值剩下1)再新增一個節點即可。
sample 22 ms submission
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
static const auto _____ = []()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
return nullptr;
}();
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *head = new ListNode(0);
ListNode *tail = head;
int carry = 0;
while(l1 || l2 || carry){
int n = (l1?l1->val:0) + (l2?l2->val:0) + carry;
tail -> next = new ListNode(n % 10);
carry = n / 10;
tail = tail -> next;
l1 = l1?l1 -> next:NULL;
l2 = l2?l2 -> next:NULL;
}
return head -> next;
}
};