2. 两数相加
https://leetcode-cn.com/problems/add-two-numbers/
难度 | 完成日期 | 耗时 | 提交次数 |
---|---|---|---|
中等 | 2020-1-10 | 3小时 | 8 |
问题描述
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807
解题思路
按照链表次序依次相加
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { ListNode *ans = new ListNode(0); ListNode *head = ans; bool add = false; while (l1 != nullptr && l2 != nullptr) { int val = l1->val + l2->val; if (add) { val++; } if (val > 9) { val = val - 10; add = true; } else { add = false; } ListNode *temp = new ListNode(val); ans->next = temp; l1 = l1->next; l2 = l2->next; ans = ans->next; } if (add) { ListNode *temp = new ListNode(1); ans->next = temp; ans = ans->next; } ListNode *l = l1 == nullptr ? l2 : l1; ans->next = l; return head->next; }
失败,思考最后一位相加进位如何解决,比如给出的测试用例中 [5], [5]
和 [9, 8], [1]
等。
转换成整数相加后转回链表
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) { int num1 = 0; int time1 = 0; while (l1 != nullptr) { int temp = l1->val; for (int i = 0; i < time1; i++) { temp = temp * 10; } time1++; num1 = num1 + temp; l1 = l1->next; } int num2 = 0; int time2 = 0; while (l2 != nullptr) { int temp = l2->val; for (int i = 0; i < time2; i++) { temp = temp * 10; } time2++; num2 = num2 + temp; l2 = l2->next; } int num = num1 + num2; if (num != 0) { ListNode *ans = new ListNode(0); ListNode *head = ans; while (num >= 1) { ListNode *temp = new ListNode(num % 10); num = num / 10; ans->next = temp; ans = ans->next; } return head->next; } else { ListNode *ans = new ListNode(0); return ans; } }
失败,链表过长超过整型范围,返回第一种思路。一开始就想到会有这种问题的存在,但还是抱着侥幸心理试了一下,果然不行。
解决相加进位的问题
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) { ListNode *ans = new ListNode(0); ListNode *head = ans; ListNode *l1head = l1; ListNode *l2head = l2; int length1 = 0; while (l1->next != nullptr) { length1++; l1 = l1->next; } int length2 = 0; while (l2->next != nullptr) { length2++; l2 = l2->next; } int diff = length1 - length2; if (diff > 0) { for (; diff > 0; diff--) { ListNode *zero = new ListNode(0); l2->next = zero; l2 = l2->next; } } else if (diff < 0) { for (; diff < 0; diff++) { ListNode *zero = new ListNode(0); l1->next = zero; l1 = l1->next; } } l1 = l1head; l2 = l2head; bool add = false; while (l1 != nullptr) { int val = l1->val + l2->val; if (add) { val++; } if (val > 9) { val = val - 10; add = true; } else { add = false; } ListNode *temp = new ListNode(val); ans->next = temp; l1 = l1->next; l2 = l2->next; ans = ans->next; } if (add) { ListNode *temp = new ListNode(1); ans->next = temp; } return head->next; }
成功,将链表补全到相同长度后再进行相加,这样一来只用考虑最后一位的进位。
来源:https://www.cnblogs.com/kennyoooo/p/12177627.html