题目
描述
假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
给定两个这种链表,请生成代表两个整数相加值的结果链表。
数据范围:0≤n,m≤1000000,链表任意值 0≤val≤9 要求:空间复杂度 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
备注:
1≤n,m≤1060≤ai,bi≤9
分析
考虑特殊情况
在进行问题分析过程前,我们先考虑一下特殊情况,那么在这道问题中,有哪些情况是特殊的呢?
不难发现,如下情况:
考虑一般情况
首先我们可以看到题目中描述的链表中的数据是从高位到低位的,但是我们正常的加法运算都是从低往高位进行计算的,所以我们可以考虑先将链表进行反转,然后再做处理。
在我们做加法运算时,可以考虑以哪一个链表作为主链表,基于这样一个原因,两个 n 位数相加,最多会生成一个 n+1 位数,所以我们可以将较长的链表作为主链表,并增加一个 pReturn 节点。
使用两个指针同时访问这两个链表,然后做加法,并进行进位操作,依次操作,最后如果进位还有标志,那就需要增加一个节点保存多余的一位信息。
由于我们使用了较长的链表作为返回信息的主要组成部分,所以在空间上面复杂度可以达到 O(1)
前面的计算信息是链表逆序的,这里我们还需要将结果链表再反过来。
如果 pReturn 节点的值为 0,那就返回 pReturn->next;
如果 pReturn 节点的值为 1,那就返回 pReturn.
题解中参考的处理步骤:
step 1:任意一个链表为空,返回另一个链表就行了,因为链表为空相当于 0,0 加任何数为 0,包括另一个加数为 0 的情况。
step 2:相继反转两个待相加的链表,反转过程可以参考反转链表。
step 3:设置返回链表的链表头,设置进位 carry=0.
step 4:从头开始遍历两个链表,直到两个链表节点都为空且 carry 也不为 1. 每次取出不为空的链表节点值,为空就设置为 0,将两个数字与 carry 相加,然后查看是否进位,将进位后的结果(对 10 取模)加入新的链表节点,连接在返回链表后面,并继续往后遍历。
注意:这里增加了新的节点,所以空间复杂度是 O(n)的。
代码示例
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */
class Solution { public: /** * * @param head1 ListNode类 * @param head2 ListNode类 * @return ListNode类 */ ListNode* addInList(ListNode* head1, ListNode* head2) { // write code here if (nullptr == head1) { return head2; } if (nullptr == head2) { return head1; }
// the head point ListNode* pReturn = new ListNode(0); ListNode* pQuick = nullptr; ListNode* pSlow = nullptr; ListNode* pLong = nullptr;
// reverse list int length1 = GetLinkListLength(head1); int length2 = GetLinkListLength(head2); ListNode* pReverse1 = ReverseLinkList(head1); ListNode* pReverse2 = ReverseLinkList(head2); pQuick = pReverse1; pLong = pReverse1; pSlow = pReverse2; if (length2 > length1) { pLong = pReverse2; pQuick = pReverse2; pSlow = pReverse1; }
int entry = 0; ListNode* pPre = nullptr; while (nullptr != pSlow || nullptr != pQuick) { int SlowVal = nullptr == pSlow ? 0 : pSlow->val;
pQuick->val += SlowVal + entry; entry = pQuick->val/10; pQuick->val %= 10;
pPre = pQuick; pQuick = pQuick->next; pSlow = nullptr == pSlow ? nullptr : pSlow->next; } pPre->next = pReturn; pReturn->val = entry;
pReturn = ReverseLinkList(pLong); if (pReturn->val == 1) { return pReturn; } else { return pReturn->next; } }
int GetLinkListLength(ListNode* head) { int length = 0; while (nullptr != head) { length++; head = head->next; } return length; }
ListNode* ReverseLinkList(ListNode* head) { if (nullptr == head || nullptr == head->next) { return head; }
ListNode* pPre = nullptr; ListNode* pCur = head; ListNode* pNext = head->next;
while (nullptr != pCur) { pNext = pCur->next; pCur->next = pPre; pPre = pCur; pCur = pNext; } return pPre; }};
复制代码
评论