LeetCode 445——两数相加 II
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的更多相关文章
- LeetCode 445. 两数相加 II(Add Two Numbers II)
445. 两数相加 II 445. Add Two Numbers II 题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个 ...
- Java实现 LeetCode 445 两数相加 II
445. 两数相加 II 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会 ...
- Leetcode 445. 两数相加 II
1.题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. ...
- 力扣 - 445. 两数相加 II
目录 题目 思路 代码实现 题目 给你两个 非空 链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储一位数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两 ...
- 445. 两数相加 II
Q: A: 这种题的用例是一定会搞一些很大的数的.long都会溢出,所以我们就不用尝试转数字做加法转链表的方法了.另外直接倒置两个链表再做加法的做法会改变原链表,题干也说了禁止改动原链表. 1.求两个 ...
- Leetcode 002. 两数相加
1.题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表 ...
- LeetCode 2. 两数相加(Add Two Numbers)
2. 两数相加 2. Add Two Numbers 题目描述 You are given two non-empty linked lists representing two non-negati ...
- 445 Add Two Numbers II 两数相加 II
给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表.你可以假设除了数字 0 之外,这两个数字都不会以零开头.进阶:如果输入链表 ...
- [Swift]LeetCode445. 两数相加 II | Add Two Numbers II
You are given two non-empty linked lists representing two non-negative integers. The most significan ...
随机推荐
- IDEA(2018.3.2)
N757JE0KCT-eyJsaWNlbnNlSWQiOiJONzU3SkUwS0NUIiwibGljZW5zZWVOYW1lIjoid3UgYW5qdW4iLCJhc3NpZ25lZU5hbWUiO ...
- SQL 存储过程生成
use workflow; GO /****** 对象: StoredProcedure [dbo].[pro_GenerateProGet] 脚本日期: 08/03/2012 11:26:43 ** ...
- show status 查看各种状态
要查看MySQL运行状态,要优化MySQL运行效率都少不了要运行show status查看各种状态,下面是参考官方文档及网上资料整理出来的中文详细解释: 如有问题,欢迎指正 状态名 作用域 详细解释 ...
- Ubuntu18.04安装完应该做的一些事 显卡驱动安装和cuda8.0
博主装Ubuntu18.04主要是为了用于跑深度学习,所以我们先来搞搞gcc环境 第一步:安装多版本gcc.g++可切换 sudo apt-get install gcc-4.8 gcc-4.8-mu ...
- jquery仿移动端支付宝键盘
最近做项目时碰到一个需求,就是在移动端支付页面点击支付按钮弹出一个支付键盘,类似于支付宝的那种.由于项目只是单纯的手机网站,而并非app,所以这个功能得由前端来实现.话不多说,先上图看看效果. 尼玛, ...
- python3.X 安装web.py 失败的解决方法
python2.x 安装python是非常顺利的 但是 在进行 pip3 install web.py 时提示很多错误 例如缺少模块 语法错误...... 最后试了一下web.py 的dev版本 pi ...
- 「PHP」抽象工厂模式
引言 所属:创建型模式,常用设计模式之一 参考资料: <大话设计模式>程杰 模式概述 官方定义:抽象工厂模式(Abstract Factory),提供一个创建一系列相关或互相 ...
- Django templates加载css/js/image等静态资源
配置步骤: 1.首先在应用下面创建static目录 2.将静态资源拷贝进去 3.在应用的settings.py文件中添加 import os BASE_PATH = os.path.dirname(o ...
- 我的名字叫hadoop
第一回 新入环境 我的名字是hadoop,我一出生我的爸爸雅虎就给我取了这样一个名字:hadoop,我也不知道为什么叫这个名字,刚出生没多久,雅虎爸爸就把我领进一个黑暗的屋子里面,屋里堆满了黑色的 ...
- STM32_1 搭建工程框架
搭建系统框架 -- 创建系统文件夹 -- 拷贝stm32库文件 -- 将文件添加至工程 -- 配置工程环境 1. 创建工程文件夹 找一个工程目录,我就在 stm32/Code 下创建一个模板工程Tem ...