トピックの説明
给定两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
进阶:
如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。
示例:
输入: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出: 7 -> 8 -> 0 -> 7
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
この質問は比較的単純で、境界条件の処理に注意するだけです。連結リストは空ではないので特別な処理は必要なく、まず2つのチェーンの長さlen1、len2と差分disを求め、加算結果をスタックに一時的に格納します。最初に長いチェーンを dis 位置に入力し、次に 2 つのチェーンの対応する位置の値を追加して入力します。前の長いチェーンが dis 位置に入りますが、これはこの時点で正確に正しいです。加算が終了すると、繰り上げられない加算結果が得られます。次に、ゆっくりとスタックを取り出し、ここでキャリーがあったかどうかを判断し、キャリーの結果を追加で計算する必要があります。ポップ後の結果は、ヘッド補間メソッドを使用して新しいチェーンを生成し、最後のノードを返します。
コードの表示
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
//先计算两者长度,然后谁长谁先进栈。到了同位的时候就一起进栈。进完后一个个出栈,用头插法生成新的链表
int len1 = 0,len2 = 0;
int maxL,dis,minL;
vector<int> res;
ListNode*p = l1,*q = l2;
while(p)
{
++len1;
p = p->next;
}
while(q)
{
++len2;
q = q->next;
}
if(len1 > len2)
{
p = l1;
q = l2;
}
else
{
p = l2;
q = l1;
}
maxL = len1>len2?len1:len2;
minL = len1>len2?len2:len1;
dis = maxL - minL;
//拿到了两者的长度l1和l2,较长的为maxL,且先移动maxL-min(l1,l2)位
for(int i = 0;i < dis;++i)
{
res.push_back(p->val);
p = p->next;
}
for(int i = 0;i < minL;++i)//相加再进栈
{
res.push_back(p->val+q->val);
p = p->next;
q = q->next;
}
//全部都放进去了,再根据这个vector来还原
p = NULL;
while(!res.empty())
{
int num = res[res.size()-1];
res.pop_back();
cout<<num<<endl;
if(num > 9)
{
if(!res.empty())
{
num -= 10;
res[res.size()-1] += 1;
}
else
{
num = num - 10;
res.push_back(1);//最后的挣扎;进位
}
}
q = new ListNode(num);
//新节点是这个,让这个新节点指向前一个节点,并更新前一个节点
q->next = p;
p = q;
}
return p;
}
};