加法模拟算法模板
LeetCode加法模板
抽象过程
十进制加法模拟:
首先我们先看十进制加法的模拟过程,如图
解析 :
- 该过程涉及到的对象有四个,分别为加数1,加数2,进位与结果和;
- 该过程隐藏的两个对象为 进制(不一定非要十进制),前导0(比如34可以看为034,在百位上发生的计数为9+1+0产生进位,百位上产生结果mod(10,10)=0);
- 该过程有两个特征,是低位开始计算,高位逐步进位;
- 该过程在看成有前导0的的前提下,是每位上的数字与进位相加后求模,不妨设数组A[0,9,9,9],数组B[0,0,3,4],进位符号carrry.
*1. 结果和的个位3为sum(9,4,0)%10=3,carry=sum(9,4,0)/10=1;
*2. 结果和的十位3为sum(9,3,1)%10=3,carry=sum(9,3,1)/10=1;
*3. 结果和的百位0为sum(9,0,1)%10=0,carry=sum(9,0,1)/10=1;
*4. 结果和的千位1为sum(0,0,1)%10=1,carry=sum(0,0,1)/10=0.
可见,该过程的结束条件为a[i]=0,b[i]=0,carry=0.
算法模板
由加法过程的抽象可以得到算法模板为
#加数A,加数B,进位carry,和C,用null代表前导0更直观,sum表示各位和
while(A!=null || B!=null || carry !=0)
{
//求sum
sum = (A!=null?A.val:0) + (B!=null?B.val:0)+carry;
//求carry
carry = sum/进制;
//创建结果和C该位上的值
C.val = sum%进制;
//下一位传递
A = A!=null?A.next:null;
B = B!=null?A.next:null;
C.next = new CNode();
C=C.next;
}
sum和carry都是每次参与加法和,所以可以优化一下为
while(A!=null || B!=null || carry !=0)
{
carry +=(A!=null?A.val:0) + (B!=null?B.val:0);
//创建结果和C该位上的值
C.val = carry%进制;
//下一位传递
A = A!=null?A.next:null;
B = B!=null?A.next:null;
C.next = new CNode();
C=C.next;
//求carry
carry = carry/进制;
}
leetCode相关题
2.两数相加
两数相加.
/** 便签 : 加法模板 链表
* 两数相加
* 描述:给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
*
* 请你将两个数相加,并以相同形式返回一个表示和的链表。
*
* 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
*
* 示例1:
* 输入:l1 = 2->4->3 l2 = 5->6->4
* 输出: 342 + 465 = 807 , 输出7->0->8
*
*
*/
public class Question2 {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
/* 初始版本
//进位标识
boolean flag = false;
ListNode l3 = null; ListNode head3 = null;
ListNode head1 = l1.next; ListNode head2 = l2.next;
int sum = 0; int var1;int var2;
//先构建新链表的头
sum = l1.val+l2.val;
if(sum>=10) flag=true; else flag=false;
l3 = new ListNode(sum%10,null);
head3 = l3;
while(head1!=null||head2!=null)
{
var1 = head1!=null?head1.val:0;
var2 = head2!=null?head2.val:0;
if(flag) sum = var1+var2+1; else sum=var1+var2;
if(sum>=10) flag=true; else flag=false;
head3.next = new ListNode(sum%10,null);
if(head1!=null) head1 = head1.next;
if(head2!=null) head2 = head2.next;
head3 = head3.next;
}
if(flag) head3.next = new ListNode(1,null);
return l3;
*/
/* 改进版本
int flag = 0;
int var1;int var2;
//先构建新链表的头
ListNode l3 = new ListNode(-1,null);
ListNode head3 = l3;
while(l1!=null||l2!=null||flag!=0)
{
if(l1!=null)
{
flag +=l1.val;
l1 = l1.next;
}
if(l2!=null)
{
flag +=l2.val;
l2 = l2.next;
}
head3.next = new ListNode(flag%10,null);
head3 = head3.next;
flag /= 10;
}
return l3.next;
*/
/*if (l1 == null) {
return l2;
}
if (l2 == null) {
return l1;
}
ListNode head = new ListNode(-1);
ListNode currentNode = head;
int carryFlag = 0;
while (l1 != null && l2 != null) {
int sum = l1.val + l2.val;
if (carryFlag == 1) {
sum ++;
carryFlag = 0;
}
if (sum >= 10) {
carryFlag = 1;
sum = sum % 10;
}
ListNode node =