题目
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例 2:
输入:l1 = [0], l2 = [0]
输出:[0]
示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]
解答
思路
定义头指针、复用变量(用于存储相加结果及进位)。
当 l1不为空 或 l2不为空(记住此处的l1和l2都是指针)或 最后一项不为进位时:
-
若 l1不为空 或 l2不为空,存储对应位的数字(同时处理进位)。
-
每处理一次都需要新建结点,同时计算进位。
需要的头文件
无。
代码
/*
* @lc app=leetcode.cn id=2 lang=cpp
*
* [2] 两数相加
*/
// @lc code=start
/**
* Definition for singly-linked list.
* struct ListNode
* {
* int val;
* struct ListNode *next;
* };
**/
class Solution
{
public:
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2)
{
//定义返回的单链表
ListNode l3;
//定义头指针
ListNode *p = &l3;
//定义相加结果及进位(复用)
int count = 0;
//当l1不空,l2不空,最后一项非进位时(类似9999+1的情况)
while (l1 || l2 || count)
{
//l1不空或l2不空都进行计算
if (l1)
{
count += l1->val;
l1 = l1->next;
}
if (l2)
{
count += l2->val;
l2 = l2->next;
}
//单链表l3新建结点
p = p->next = new ListNode();
p->val = count % 10;
//若count>10表明有进位,下次count必为1
count /= 10;
}
return l3.next;
}
};
时间复杂度和空间复杂度
- 时间复杂度:无论如何我们都需要遍历最长的那个数组,所以为 O(max(m,n)) ,其中m,n为l1和l2的链表长度。
- 空间复杂度:两数相加的极端情况可以视作 比两个加数中最长的一个还多一位。所以为 O(max(m,n)) 。
反思与总结
- 单链表定义的数据结构不同,使用的时候语句形式就有所不同(如申请头指针是否带*),Leetcode只要求实现solution,平时一定要结合vs进行实际的程序test,弄明白意义。
- 相加结果与进位的复用思想。