文章目录
- 前言
- 题目
- 解决方案一
- 1.1 思路阐述
- 1.2 源码
- 总结
前言
这道题使用链表来实现加法运算,主要是涉及到数据对位以及加法进位的处理。
题目
假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
给定两个这种链表,请生成代表两个整数相加值的结果链表。
数据范围: 0 ≤ n , m ≤ 1000000 0≤n,m≤1000000 0≤n,m≤1000000,链表任意值 0 ≤ v a l ≤ 9 0≤val≤9 0≤val≤9
要求:空间复杂度 O ( n ) O(n) O(n),时间复杂度 O ( n ) O(n) O(n)
例如:链表 1 为 9->3->7,链表 2 为 6->3,最后生成新的结果链表为 1->0->0->0。
示例1
输入:[9,3,7],[6,3]
返回值:{1,0,0,0}
说明:如题面解释
示例2
输入:[0],[6,3]
返回值:{6,3}
备注:
1 ≤ n , m ≤ 1 0 6 1≤n,m≤10^6 1≤n,m≤106
0 ≤ a i , b i ≤ 9 0≤ai,bi≤9 0≤ai,bi≤9
解决方案一
1.1 思路阐述
加法运算一般是个位个位相加,十位十位相加…。也就是说数据要对位才可以相加,就如同题目中给出的加法运算的标准列式计算。
但是对于被加数和加数之间,由于它们是由两个链表存储,由于两个数之间的位数的大小不一样,所以链表存储的节点个数不一样,如果按照从左往右的顺序进行运算,我们可以看到题目给的图中的情况,9和6会相加,但是实际上是900+60这种,位数并不对应。应该执行的操作应该是900+0,30+60。
但是由于链表最后一个存储的节点一定是个位数,往左依次是十位百位,所以在链表中我们可以考虑从右往左的顺序,但是这与我们所用的加法运算的顺序(从左往右)相反,这时候可以使用链表倒置,对于最后的结果再次倒置即为我们所需要的链表。
关于链表倒置参考博客:C/C++ BM1反转链表
两数相加,逢十进一,这里我们设置了一个进位carry。
对于节点,我们首先判断节点是否为空,如果为空,则取0值作为运算数据。(这里相当于补0操作)
如果不为空则把节点的值传递给运算值。
1.2 源码
class Solution {public:ListNode* addInList(ListNode* head1, ListNode* head2) {head1 = reverseList(head1);head2 = reverseList(head2);//添加表头ListNode* res = new ListNode(-1);ListNode* head = res;int carry = 0;while (head1 != NULL || head2 != NULL || carry != 0) {//链表不为空则取其值int val1 = head1 == NULL ? 0 : head1->val;int val2 = head2 == NULL ? 0 : head2->val;//相加int temp = val1 + val2 + carry;//获取进位carry = temp / 10;temp %= 10;//添加元素head->next = new ListNode(temp);head = head->next;//移动下一个if (head1 != NULL)head1 = head1->next;if (head2 != NULL)head2 = head2->next;}return reverseList(res->next); }ListNode* reverseList(ListNode* head) {if (!head) {return nullptr;}ListNode* pre = nullptr;ListNode* current = head;while (current) {ListNode* temp = current->next;current->next = pre;pre = current;current = temp;}return pre;}
};
总结
这道题回顾了一下链表翻转。
对于链表的四则运算涉及到对位情况,考虑使用翻转链表会更好。不能按照常规的四则运算从左到右的顺序来做,要结合链表本身的特性来做。