力扣算法之加法模拟

LeetCode加法模板

抽象过程

十进制加法模拟:
首先我们先看十进制加法的模拟过程,如图
Alt
解析 :

  1. 该过程涉及到的对象有四个,分别为加数1,加数2,进位与结果和
  2. 该过程隐藏的两个对象为 进制(不一定非要十进制),前导0(比如34可以看为034,在百位上发生的计数为9+1+0产生进位,百位上产生结果mod(10,10)=0);
  3. 该过程有两个特征,是低位开始计算,高位逐步进位;
  4. 该过程在看成有前导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 = 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值