1. 题目

2. 解答

2.1 方法一

LeetCode 206——反转链表LeetCode 2——两数相加 的基础上,先对两个链表进行反转,然后求出和后再进行反转即可。

/**
* 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) { // 先将两个链表反序
l1 = reverseList(l1);
l2 = reverseList(l2); ListNode *head = new ListNode(0); // 建立哨兵结点
ListNode *temp = head; int carry = 0; // 保留进位
int sum = 0; while(l1 || l2)
{
if (l1 && l2) // 两个链表都非空
{
sum = l1->val + l2->val + carry;
l1 = l1->next;
l2 = l2->next;
}
else if (l1) // l2 链表为空,只对进位和 l1 元素求和
{
sum = l1->val + carry;
l1 = l1->next;
}
else // l1 链表为空,只对进位和 l2 元素求和
{
sum = l2->val + carry;
l2 = l2->next;
} // 求出和以及进位,将和添加到新链表中
carry = sum >= 10 ? 1 : 0;
sum = sum % 10;
head->next = new ListNode(sum);
head = head->next; if ( (l1 == NULL || l2 == NULL) && carry == 0 )
{
head->next = l1 ? l1 : l2;
return reverseList(temp->next);
} } if (carry) // 若最后一位还有进位,进位即为最后一位的和
{
head->next = new ListNode(carry);
}
head->next->next = NULL; return reverseList(temp->next); } ListNode* reverseList(ListNode* head) { if (head == NULL || head->next == NULL) return head;
else
{
ListNode * p1 = head;
ListNode * p2 = p1->next;
ListNode * p3 = p2->next; while (p2)
{
p3 = p2->next; p2->next = p1;
p1 = p2;
p2 = p3;
}
head->next = NULL;
head = p1; return head;
} } };
2.2 方法二

先求出两个链表的长度,然后对齐两个链表,按照对应位分别求出每一位的和以及进位,最后从最低位也就是最右边开始,将和与进位相加,新建节点在链表头部插入即可。

例 1
l1 7 2 4 3
l2 5 6 4
7 7 0 7
进位 0 1 0 0
结果 7 8 0 7
例 2
l1 9 9 9
l2 9 9
0 9 8 8
进位 0 1 1 0
结果 1 0 9 8
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { int n1 = countListNodeNumber(l1);
int n2 = countListNodeNumber(l2); ListNode* long_list = NULL;
ListNode* short_list = NULL;
int bigger_n = 0;
int smaller_n = 0; if (n1 <= n2)
{
long_list = l2;
short_list = l1;
bigger_n = n2;
smaller_n = n1;
}
else
{
long_list = l1;
short_list = l2;
bigger_n = n1;
smaller_n = n2;
}
int temp = bigger_n - smaller_n + 1;
int sum_array[bigger_n + 1] = {0};
int carry_array[bigger_n + 1] = {0};
int sum = 0;
int carry = 0; ListNode* long_temp = long_list;
ListNode* short_temp = short_list; for (unsigned int i = 1; i <= bigger_n; i++)
{
carry = 0;
if (i < temp)
{
sum = long_temp->val;
}
else
{
sum = long_temp->val + short_temp->val;
if (sum >= 10)
{
sum = sum % 10;
carry = 1;
}
short_temp = short_temp->next;
}
sum_array[i] = sum;
carry_array[i-1] = carry;
long_temp = long_temp->next;
} ListNode* new_head = new ListNode(0);
long_temp = new_head; for (unsigned int i = bigger_n; i > 0; i--)
{
// 在链表头部进行插入
sum = sum_array[i] + carry_array[i];
if (sum >= 10)
{
sum = sum % 10;
carry_array[i-1] = 1;
}
short_temp = new ListNode(sum);
short_temp->next = long_temp->next;
long_temp->next = short_temp;
} sum = sum_array[0] + carry_array[0];
if (sum)
{
short_temp = new ListNode(sum);
short_temp->next = long_temp->next;
long_temp->next = short_temp;
} return new_head->next; } int countListNodeNumber(ListNode *head)
{
int node_num = 0;
ListNode* slow = head;
ListNode* fast = head; while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
node_num++;
} if (fast)
{
node_num = node_num * 2 + 1;
}
else
{
node_num = node_num * 2;
} return node_num;
} };
2.3 方法三

将两个链表的节点分别放入两个栈中,若两个栈都非空,拿两个栈顶元素和进位,求出和以及新的进位;若其中一个栈为空,则拿一个栈顶元素和进位,求出和以及新的进位。然后新建节点,在链表头部进行插入,最后只用处理一下最高位的进位即可。

class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { stack<ListNode *> stack1;
stack<ListNode *> stack2; while (l1)
{
stack1.push(l1);
l1 = l1->next;
} while (l2)
{
stack2.push(l2);
l2 = l2->next;
} int sum = 0;
int carry = 0; ListNode *new_head = new ListNode(0);
ListNode *temp = NULL; while (!stack1.empty() && !stack2.empty())
{
sum = stack1.top()->val + stack2.top()->val + carry; if (sum >= 10)
{
sum = sum % 10;
carry = 1;
}
else
carry = 0; temp = new ListNode(sum);
temp->next = new_head->next;
new_head->next = temp; stack1.pop();
stack2.pop();
} while (!stack1.empty())
{
sum = stack1.top()->val + carry; if (sum >= 10)
{
sum = sum % 10;
carry = 1;
}
else
carry = 0; temp = new ListNode(sum);
temp->next = new_head->next;
new_head->next = temp; stack1.pop();
} while (!stack2.empty())
{
sum = stack2.top()->val + carry; if (sum >= 10)
{
sum = sum % 10;
carry = 1;
}
else
carry = 0; temp = new ListNode(sum);
temp->next = new_head->next;
new_head->next = temp; stack2.pop();
} if (carry)
{
temp = new ListNode(carry);
temp->next = new_head->next;
new_head->next = temp;
} return new_head->next;
}
};

获取更多精彩,请关注「seniusen」!

LeetCode 445——两数相加 II的更多相关文章

  1. LeetCode 445. 两数相加 II(Add Two Numbers II)

    445. 两数相加 II 445. Add Two Numbers II 题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个 ...

  2. Java实现 LeetCode 445 两数相加 II

    445. 两数相加 II 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会 ...

  3. Leetcode 445. 两数相加 II

    1.题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. ...

  4. 力扣 - 445. 两数相加 II

    目录 题目 思路 代码实现 题目 给你两个 非空 链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储一位数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两 ...

  5. 445. 两数相加 II

    Q: A: 这种题的用例是一定会搞一些很大的数的.long都会溢出,所以我们就不用尝试转数字做加法转链表的方法了.另外直接倒置两个链表再做加法的做法会改变原链表,题干也说了禁止改动原链表. 1.求两个 ...

  6. Leetcode 002. 两数相加

    1.题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表 ...

  7. LeetCode 2. 两数相加(Add Two Numbers)

    2. 两数相加 2. Add Two Numbers 题目描述 You are given two non-empty linked lists representing two non-negati ...

  8. 445 Add Two Numbers II 两数相加 II

    给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表.你可以假设除了数字 0 之外,这两个数字都不会以零开头.进阶:如果输入链表 ...

  9. [Swift]LeetCode445. 两数相加 II | Add Two Numbers II

    You are given two non-empty linked lists representing two non-negative integers. The most significan ...

随机推荐

  1. ORACLE_HOME_LISTNER is not SET, unable to auto-start Oracle Net Listener

    执行$ORACLE_HOME/bin/dbstart 启动数据库提示如下: [oracle@prim bin]$ ./dbstart ORACLE_HOME_LISTNER is not SET, u ...

  2. Mysql的TIMESTAMPDIFF和TIMESTAMPADD的用法

    [1.]TIMESTAMPDIFF(interval,colum1,colum2) 字段类型:date或者datetime 计算过程:colum2减去colum1,即后面的减去前面的 计算结果:整数 ...

  3. morphia 框架 mongodb内嵌查询

    mongodb中存储的文档格式如下,实现查询fromdata下did和dvid为指定值的数据 { "_id": { "$oid": "553f4a9f ...

  4. 记一次MySQL中Waiting for table metadata lock问题的处理

    起因:由于需要,要把一张表的一个字段从不是 null 改成 可null,我用的Navicat Premium ,但是在保存的时候,工具无响应了,几个同事操作都是这样的,很奇怪,怀疑是不是由于表被锁了还 ...

  5. Resharp常用设置收集整理

    F12跳转的问题:

  6. 【若泽大数据实战第二天】Linux命令基础

    Linux基本命令: 查看IP: ifconfig 或者 hostname -i(需要配置文件之后才可以使用) ipconfig(Windows) 关闭防火墙: Service iptables st ...

  7. yii学习笔记(6),数据库操作(增删改)

    数据库增删改操作通过活动记录实例来完成 插入记录 /* ----------添加记录---------- */ // 创建活动记录对象 $article = new Article(); $artic ...

  8. ov5640介绍

    1 摄像头 在各类信息中,图像含有最丰富的信息,作为机器视觉领域的核心部件,摄像头被广泛地应用在安防.探险以及车牌检测等场合.摄像头按输出信号的类型来看可以分为数字摄像头和模拟摄像头,按照摄像头图像传 ...

  9. Android零碎知识点

    1.android:foreground="?attr/selectableItemBackground"   ###设置水波纹效果 2.android:contentDescri ...

  10. PHP.52-TP框架商城应用实例-前台4-商品详情页-面包屑导航、AJAX浏览历史

    面包屑导航  思路:根据商品的主分类向上取出所有上级分类即可 1.在分类模型中增加取出所有上级分类的方法 /********** [面包屑导航]取出一个分类所有上级分类 **********/ pub ...