【链表】Add Two Numbers
题目:
You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
思路:
从左到右相加,记录进位值。
注意:两个链表不同长度,及链表相加后也要检验进位是否为0。
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var addTwoNumbers = function(l1, l2) {
var carrybit=0,tempHead=new ListNode(0);
var p=tempHead; while(l1&&l2){
l1.val+=l2.val+carrybit;
carrybit=l1.val/10;
l1.val=l1.val%10;
p.next=l1;
p=p.next; l1=l1.next;
l2=l2.next; } var lp=(l1==null?l2:l1); while(lp){
if(carrybit==0){
p.next=lp;
break;
}else{
lp.val+=carrybit;
carrybit=lp.val/10;
lp.val=lp.val%10;
p.next=lp;
p=p.next;
}
lp=lp.next;
} if(carrybit!=0){
p.next=new ListNode(carrybit);
} return tempHead.next;
};
如果链表存储整数时,高位在前,该如何处理。
1、最简单的想法是,可以先把链表反转,然后调用上面的算法,最后把结果反转。
2、可不可以从高位向低位方向处理呢?我们知道进位是从低位传向高位的,如果从高位向低位方向计算,当计算到某一位需要进位时,有没有办法知道该进位传递到前面的哪一位呢?从以下几个例子来看:
从最高位到最低位我们依次记为第 1,2…,7位。图中红色标记的位置是:下一次需要进位时,进位的1放置的位子
第1位相加,结果为12,需要进位,这个进位放到第0位;同时标记第1位为下一次的进位标志
第2位相加,结果为3,不需要进位;标记第2位为下一次进位标志
第3位相加,结果为3,不需要进位;标记第3位为下一次进位标志
第4位相加,结果为9,不需要进位;此时进位标志不需要移动,因为9加上一个进位后还要继续向前进位
第5位相加,结果为9,不需要进位;此时进位标志不需要移动,因为9加上一个进位后还要继续向前进位
第6位相加,结果为14,需要进位,这个进位放到前面标记的第3位上,同时把第4位和第5位置0,标记第6位为下一次进位标志
第7位同上
所以综上所述,从高位往低位计算加法时,规则是:
一、如果当前位没有进位:(1)如果当前位的和小于9,则把改位设置成下一次进位标志(2)如果和等于9,进位标志不变
二、如果当前位有进位:把进位的1加到前面标志的位子上,同时把标志位和当前位之间的位全部置0(因为他们之间的位肯定全部都是9),把当前位设置成进位标志
上面我们举例的两个加数长度一致,如果长度不相同,则要先处理较长的整数的前面多出的部分。
我们把这一题leetcode的输入反转,测试代码如下:
/**
* 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);
int n1 = lenList(l1), n2 = lenList(l2);
if(n1 < n2)//l1 指向较长的链表
{
swap(n1,n2);
swap(l1,l2);
}
//carryLoc是下一次出现进位时,进位的1将要放置的位子,pre指向当前结果链表的最后一个节点
//p1,p2分别是当前处理的l1,l2节点
//由于加数的最高位有可能进位,所以添加一个新的节点newHead
ListNode *newHead = new ListNode(), *carryLoc = newHead, *pre = newHead, *p1 = l1;
for(int i = ; i < n1-n2; i++)//处理l1高位长出的部分
{
if(p1->val < )carryLoc = p1;
pre->next = p1;
pre = p1;
p1 = p1->next;
}
ListNode* p2 = l2;
while(p1 != NULL)
{
pre->next = p1;
pre = p1; p1->val += p2->val;
if(p1->val > )
{
carryLoc->val += ;
for(carryLoc = carryLoc->next; carryLoc != p1; carryLoc = carryLoc->next)//carryLoc到p1之间的节点全部置0
carryLoc->val = ;
p1->val -= ;
}
if(p1->val < )
carryLoc = p1; p1 = p1->next;
p2 = p2->next;
}
if(newHead->val != )return reverseList(newHead);
else return reverseList(newHead->next);
}
//反转链表
ListNode *reverseList(ListNode *l1)
{
ListNode *p = l1->next, *pre = l1;
l1->next = NULL;
while(p)
{
ListNode *tmp = p->next;
p->next = pre;
pre = p;
p = tmp;
}
return pre;
}
//求链表长度
int lenList(ListNode *head)
{
int res = ;
while(head)
{
res++;
head = head->next;
}
return res;
}
};
【链表】Add Two Numbers的更多相关文章
- 链表-Add Two Numbers
第一版代码(很挫很罗嗦,不过是第一次做,记录一下成长的脚步!继续努力!) /*struct ListNode { int val; struct ListNode *next; };*/ typede ...
- Add Two Numbers - C++链表操作
题目意思很简单,两个链表分别表示两个数,将两个数相加的结果存入一个新的链表中. 思路同样很简单:两个链表如果一样长,对应位置相加,如果某一个链表多了,则根据加的结果有无进位继续处理,全部结束后要考虑会 ...
- LeetCode 2. add two numbers && 单链表
add two numbers 看题一脸懵逼,看中文都很懵逼,链表怎么实现的,点了debug才看到一些代码 改一下,使本地可以跑起来 # Definition for singly-linked li ...
- 链表求和12 · Add Two Numbers
反向存储,从左往右加 [抄题]: 你有两个用链表代表的整数,其中每个节点包含一个数字.数字存储按照在原来整数中相反的顺序,使得第一个数字位于链表的开头.写出一个函数将两个整数相加,用链表形式返回和.给 ...
- LeetCode 第二题 Add Two Numbers 大整数加法 高精度加法 链表
题意 You are given two non-empty linked lists representing two non-negative integers. The digits are s ...
- [LeetCode] Add Two Numbers II 两个数字相加之二
You are given two linked lists representing two non-negative numbers. The most significant digit com ...
- [LeetCode] Add Two Numbers 两个数字相加
You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...
- [CareerCup] 2.5 Add Two Numbers 两个数字相加
2.5 You have two numbers represented by a linked list, where each node contains a single digit. The ...
- No.002 Add Two Numbers
Add Two Numbers Total Accepted: 160702 Total Submissions: 664770 Difficulty: Medium You are given tw ...
- leetcode 第二题Add Two Numbers java
链接:http://leetcode.com/onlinejudge Add Two Numbers You are given two linked lists representing two n ...
随机推荐
- 常用的SLAM解决方案
ORB SLAM 可以去Github上自己搜索现成的SLAM程序包 在此基础上做优化 视觉SLAM的分类方法:按摄像头的多少分为单目和双目,按是否使用概率方法分为概率法和图法 链接 学习SLAM重要的 ...
- netty 原理
netty 实现 1. 各组件之间的关系 每个ServerBootstrap与一个事件循环对象(一个线程)都会与一个Channel绑定,如NioServerSocketChannel 2. 如何绑定 ...
- HDU1426 Sudoku Killer(DFS暴力) 2016-07-24 14:56 65人阅读 评论(0) 收藏
Sudoku Killer Problem Description 自从2006年3月10日至11日的首届数独世界锦标赛以后,数独这项游戏越来越受到人们的喜爱和重视. 据说,在2008北京奥运会上,会 ...
- Win7_Ultimate + VS2010 + openGL 配置
Win7_Ultimate + VS2010 + openGL 配置 0. 前言 OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性. (1)与C语言紧密结合. O ...
- MDX示例:求解中位数、四分位数(median、quartile)
一个人力资源咨询集团通过网络爬虫采集手段将多个知名招聘网站上发布的求职和招聘等信息准实时采集到自己的库里,形成一个数据量浩大的招聘信息库,跟踪全国招聘和求职的行业.工种.职位.待遇等信息,并通过商业智 ...
- 集合(六)LinkedHashMap
上两篇文章讲了HashMap和HashMap在多线程下引发的问题,说明了,HashMap是一种非常常见.非常有用的集合,并且在多线程情况下使用不当会有线程安全问题. 大多数情况下,只要不涉及线程安全问 ...
- python 发qq邮件
import smtplibfrom email.mime.text import MIMETextmsg_from = '979477675@qq.com' # 发送方邮箱passwd = 'irg ...
- rabbitMQ的简单实例——amqp协议带数据回写机制
rabbitMQ是一种高性能的消息队列,支持或者说它实现了AMQP协议(advanced message queue protocol高级消息队列协议). 下面简单讲一讲一个小例子.我们首先要部署好r ...
- Spring 开发第一步(三)Spring与JDBC
<spring in action 3rd>中的前面4章讲解的是Spring的核心,也就是DI/IOC和AOP .从第5章开始是Spring在企业开发中的各个方面的应用.其实作为笔者从事的 ...
- LeetCode题解-147 对链表进行插入排序
对链表进行插入排序. 插入排序的动画演示如上.从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示). 每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中. 插 ...