两数相加-一看就懂,非常详细code解法解释

        给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。

你可以假设除了数字 0 之外,这两个数字都不会以零开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

解法:

      这个题目隐藏的坑就是,你不能用任何数据结构来存放链表的整数,否则都会有溢出的风险和bug。基于此就不用想其他数据结构存2个数再求和了。

正确思路:

      这个题设计的非常好也很好实现,顺序遍历两个表,将结果存放另一个链表里,同时需要一个临时变量存放进位数值。

code:

package algorithms;

/**
 * LeetCode 两数相加
 *
 给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。
 你可以假设除了数字 0 之外,这两个数字都不会以零开头。

 示例:
 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
 输出:7 -> 0 -> 8
 原因:342 + 465 = 807
 */
public class LinkAddTwoNumbers {
    public static class ListNode {
        int val;
        ListNode next;
        ListNode(int x) {
            val = x;
        }
    }

    public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        /**
         * 以下三个变量是解法核心变量
         */
        ListNode res = null;//结果链表
        ListNode cur = null;//结果链表的游标,链接构建过程都需要有游标,否则链表构建会有问题
        int upBit = 0;//进位值


        while (l1 != null) {//任意,先遍历l1链表
            int l1Var = l1.val;//取得链表1的值
            int l2Var = 0;//定义链表2的变量,因为这个链表的长度可能小于1链表
            if (l2 != null) {//如果链表2还有值
                l2Var = l2.val;//取值
                l2 = l2.next;//下移链表游标,在这个算法里,l1,l2都是链表的游标,用于取值;而cur变量就是用来做结果集的游标并且辅助构建链表
            }
            int r = l1Var + l2Var + upBit;//将进位的值,两个链表当前位次的值相加求和
            upBit = r / 10;//除以10,求得进位数
            int thisR = r % 10;//求余10求得当前位次的值
            l1 = l1.next;//下于游标
            ListNode thisRNode = new ListNode(thisR);//构建被位次node节点
            if (res == null) {
                res = thisRNode;
                cur = res;//时刻记得移动结果游标
            } else {
                cur.next = thisRNode;
                cur = thisRNode;//时刻记得移动结果游标
            }
        }
        while (l2 != null) {//l1的长度小于l2的长度
            int l2Var = l2.val;
            int r = l2Var + upBit;
            upBit = r / 10;
            int thisR = r % 10;
            l2 = l2.next;
            ListNode thisRNode = new ListNode(thisR);
            if (res == null) {
                res = thisRNode;
                cur = res;
            } else {//时刻记得移动结果游标
                cur.next = thisRNode;
                cur = thisRNode;
            }
        }
        if (upBit != 0) {//l1,l2长度长度,但有进位,比如[5],[5] 的情况
            ListNode thisRNode = new ListNode(upBit);
            cur.next = thisRNode;
        }
        return res;
    }

    public static void main(String[] args) {
        //1
        ListNode a = new ListNode(2);
        ListNode b = new ListNode(4);
        ListNode c = new ListNode(3);

        ListNode d = new ListNode(5);
        ListNode e = new ListNode(6);
        ListNode f = new ListNode(4);
        a.next = b;
        b.next = c;
        d.next = e;
        e.next = f;
        //2
        ListNode aa = new ListNode(5);
        ListNode bb = new ListNode(5);
        //3
        ListNode aaa = new ListNode(1);
        ListNode g = new ListNode(9);
        ListNode h = new ListNode(9);
        g.next = h;


        //ListNode r = addTwoNumbers(a,d);//1,[2,4,3]和[5,6,4] ,结果,[7,0,8]
        //ListNode r = addTwoNumbers(aa,bb);2, [5]和[5],结果是[0,1]
        ListNode r = addTwoNumbers(aaa, g);//3,[1] 和[9,9],结果是[001]
        while (r != null) {
            System.out.println(r.val);
            r = r.next;
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值