(LeetCode刷题)2. 两数相加
题目


解答一:
简单实现思路:先遍历完两个链表,把各自的数字存入两个数组,然后对应位置的数相加,若结果大于10就进位到更高位的数。
/**
* Definition for singly-linked list->
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode *head = NULL, *tail = NULL;
int carry = 0;
while (l1 || l2) {
int n1 = l1 ? l1->val : 0;
int n2 = l2 ? l2->val : 0;
int sum = n1 + n2 + carry;
if (!head) {
head = tail = (struct ListNode*)malloc(sizeof(struct ListNode));
tail->val = sum % 10;
tail->next = NULL;
} else {
tail->next = (struct ListNode*)malloc(sizeof(struct ListNode));
tail->next->val = sum % 10;
tail->next->next = NULL;
tail = tail->next;
}
carry = sum / 10;
if (l1) {
l1 = l1->next;
}
if (l2) {
l2 = l2->next;
}
}
if (carry > 0) {
tail->next = (struct ListNode*)malloc(sizeof(struct ListNode));
tail->next->val = carry;
tail->next->next = NULL;
}
return head;
}算法的时间复杂度就是O(N)。因为不论怎样,只要能够找到一个答案,你都必须遍历所有的数字,无法再进一步精简遍历的次数。
解答二:
不过,我们同样可以用O(N)的时间复杂度,但是可以减少代码的复杂性和提高运行的效率。我们可以使用以下策略:边遍历链表边进行加法计算并生成新的节点,然后利用一个carry变量存储进位的值,这样可以避免多次遍历和额外的存储空间。例如:
/**
* Definition for singly-linked list->
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode *head = NULL, *tail = NULL;
int carry = 0;
while (l1 || l2 || carry) {
int sum = carry;
if (l1) {
sum += l1->val;
l1 = l1->next;
}
if (l2) {
sum += l2->val;
l2 = l2->next;
}
struct ListNode *node = (struct ListNode*)malloc(sizeof(struct ListNode));
node->val = sum % 10;
node->next = NULL;
carry = sum / 10;
if (!head) {
head = node;
} else {
tail->next = node;
}
tail = node;
}
return head;
}


