Leetcode 002. 两数相加
1.题目描述
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
2.我的错误版本
2.1 解题思路
题中链表顺序正好是低位到高位,先低位相加,有进位保持,下一位计算加上进位,直到最高位相加,如果有进位,生成新的结点保存。
2.2 我的错误代码
有时候,从错误中才能学到真知识。
现在刷题,很容易到网上找到各种答案,因此,初学者往往因为无法忍受一遍又一遍的调试,而放弃独立思考,选择取拷贝别人的代码,以理解别人的代码代替了自己刷题的那个拔高的训练过程,这实在是很可惜的,刷题的效果会大打折扣。
我的错误:
- 应当创建新的链表来保存结果,保留原链表。因为传入原链表L1和L2可能还需要用到,不能轻易更改;
- 解题思路不对:
- a.用了繁琐的思路
- b.用了繁琐的思路但没有列举全所有可能的情况:(1)两个链表一样长;(2)L1比L2长;(3)L2比L1长;(4)两个链表均为单结点,如5和5,这个测试用例反复修改,过不了,最后发现要换思路才能过。(方法不对,努力白费)
- c.链表遍历,不用遍历到NULL,处理NULL很繁琐。
//执行结果错误,方法不对,努力白费,用这个思路改了好多遍,放弃了这个错误或繁琐的思路。
//没有创建全新的链表,使用L1、L2中较长的保存结果
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { unsigned int count1 = , count2 = ;//统计两个链表长度
unsigned int carry = ; //进位 while (l1 != NULL && l2 != NULL)
{
l1->val = (l1->val + l2->val + carry) % ;
l2->val = (l1->val + l2->val + carry) % ; //判断有无进位
if ((l1->val + l2->val + carry) / != )
carry = ;
else
carry = ; // ((l1->val + l2->val + carry) / 10 != 0)?carry = 1 : carry = 0 ; l1 = l1->next;
l2 = l2->next;
} if (l1 != NULL)
{ //L1更长,剩余链表处理
while (l1 != NULL)
{
l1->val = (l1->val + carry) % ;
if ((l1->val + carry) / != )
carry = ;
else
carry = ;
l1 = l1->next;
}
if (l1 == NULL && carry == )
ListNode();
return l1;
}
else
{ //L2更长,剩余链表处理
while (l2 != NULL)
{
l2->val = (l2->val + carry) % ;
if ((l2->val + carry) / != )
carry = ;
else
carry = ;
l2 = l2->next;
}
if (l2 == NULL && carry == )
ListNode();
return l2;
} }
};
3.正确简洁版本
好的代码应该用比较通用的形式,概括表达出所有可能的情况。代码中红色标注的行是关键行。
//一般地,建议建立新链表保存结果,不在原链表上直接做修改,因为原链表可能还要使用。 #include <iostream>
#include <vector> using namespace std; struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
}; typedef ListNode* LinkList; class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { unsigned int carry = ; //进位 ListNode* Hl3 = new ListNode();//头节点
ListNode* l3 = Hl3; int a = ;
int b = ;
int temp = ; while (l1 != NULL || l2 != NULL)
{
//判断a和b的取值
if (l1 == NULL) a = ;
else a = l1->val;
if (l2 == NULL) b = ;
else b = l2->val; //a = (l1==NULL?) 0 : l1->val;
//b = (l2==NULL?) 0 : l2->val;
temp = (a + b + carry) % 10; //有无进位
if ((a + b + carry) / != )
carry = ;
else
carry = ; //创建新结点,保存temp
l3->next = new ListNode(temp);
l3 = l3->next; if (l1) l1 = l1->next;
if (l2) l2 = l2->next;
} //最后的进位
if (carry == ) {
l3->next = new ListNode();
} return Hl3->next; }
}; int main()
{
ListNode* p1 = new ListNode();
ListNode* p2 = new ListNode();
ListNode* p3 = new ListNode();
p1->next = p2;
p2->next = p3;
p3->next = NULL; ListNode* q1 = new ListNode();
ListNode* q2 = new ListNode();
ListNode* q3 = new ListNode();
q1->next = q2;
q2->next = q3;
q3->next = NULL; Solution test;
ListNode* t1 = test.addTwoNumbers(p1, q1);
while (t1) {
cout << t1->val << endl;
t1 = t1->next;
}
return ;
} //可能的问题:内存泄漏,创建的头节点Hl3最终没有被释放。
4.用时更少的范例
//来源:Leetcode官网提交的答案
//基本思路和方式是相似的 /*
*
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/ //优化C++I/O提速
static const auto __ = []() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
return nullptr;
}(); class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* L_result = new ListNode();
ListNode* a = l1;
ListNode* b = l2;
ListNode*cur = L_result;
int carry = ;
while(a != NULL || b != NULL)
{
int val1 = a != NULL ? a->val : ;
int val2 = b != NULL ? b->val : ;
int sum = val1 + val2 + carry;
carry = bool(sum / );
cur->next = new ListNode(sum %); //先判是否为空,再赋值
if(a != NULL)
{
a = a->next;
}
if(b != NULL)
{
b = b->next;
}
cur = cur->next;
}
if(carry)
{
cur->next = new ListNode();
}
return L_result->next; }
}; //可能的问题:内存泄漏,创建的头节点L_result最终没有被释放。
5.两数相加 II
跳转另一篇博客:Leetcode 445. 两数相加 II
参考资料:
1. [LeetCode] Add Two Numbers 两个数字相加
Leetcode 002. 两数相加的更多相关文章
- LeetCode 445——两数相加 II
1. 题目 2. 解答 2.1 方法一 在 LeetCode 206--反转链表 和 LeetCode 2--两数相加 的基础上,先对两个链表进行反转,然后求出和后再进行反转即可. /** * Def ...
- Leetcode 445. 两数相加 II
1.题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. ...
- LeetCode 445. 两数相加 II(Add Two Numbers II)
445. 两数相加 II 445. Add Two Numbers II 题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个 ...
- LeetCode 2. 两数相加(Add Two Numbers)
2. 两数相加 2. Add Two Numbers 题目描述 You are given two non-empty linked lists representing two non-negati ...
- LeetCode 2——两数相加(JAVA)
给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和 ...
- Java实现 LeetCode 2 两数相加
两数相加 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...
- leetcode TOP100 两数相加
两数相加 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...
- 【LeetCode】两数相加
题目描述 给出两个非空的链表用来表示两个非负的整数.其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和. ...
- leetcode 链表 两数相加
两数相加 给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例 ...
随机推荐
- 【递归入门】组合+判断素数:dfs(递归)
题目描述 已知 n 个整数b1,b2,…,bn,以及一个整数 k(k<n).从 n 个整数中任选 k 个整数相加,可分别得到一系列的和. 例如当 n=4,k=3,4 个整数分别为 3,7,12, ...
- Spring 3整合Quartz 2实现定时任务:动态添加任务
先展示一下后台管理定时任务效果图: 1.新增任务页面: 2.列表页(实现任务的禁用启用) 3.数据库脚本: -- ------------------------------ Table struct ...
- 软件工程 作业part1 自我介绍
自我介绍 老师您好,我叫宋雨,本科在长春理工大学,专业是计算机科学与技术. 1.回想一下你曾经对计算机专业的畅想:当初你是如何做出选择计算机专业的决定?你认为过去接触的课程是否符合你对计算机专业的期待 ...
- 欢迎来怼——第14次Scrum会议(10/26)
一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华 小组照片 二.开会信息 时间:2017/10/26 17:00~17:13(总计13min).地点:计 ...
- RXSwift--登录注册那点事
在iOS学习中登录注册是一个万能的可以拿出来实战的demo.接下来我们就从登录开始入手,PS:如果你对RXSwift中的概念和一些常用的函数不清楚可以参考这篇文章(可能打开比较慢请耐心等待).开始直接 ...
- <Effective C++>读书摘要--Resource Management<二>
<Item 15> Provide access to raw resources in resource-managing classes 1.You need a way to con ...
- 【Linux】- mv命令
Linux mv命令用来为文件或目录改名.或将文件或目录移入其它位置. 语法 mv [options] source dest mv [options] source... directory 参数说 ...
- java 基础 --多态--009
1, 多态:同一个对象(事物),在不同时刻体现出来的不同状态 2, 多态的前提: A: 要有继承关系 B: 要有方法的重写 C: 要有父类引用指向子类对象 父 f = new 子(); 3, 多态访问 ...
- 【转】Jsp自定义标签详解
一.前言 原本是打算研究EXtremeComponents这个jsp标签插件,因为这个是自定义的标签,且自身对jsp的自定义标签并不是非常熟悉,所以就打算继续进行扫盲,开始学习并且整理Jsp自定义标签 ...
- ping traceroute原理
ping命令工作原理 ping命令主要是用于检测网络的连通性. Ping命令发送一个ICMP请求报文给目的IP,然后目的IP回复一个ICMP报文. 原理:网络上的机器都有唯一确定的IP地址,我们给目标 ...