java算法:两个数字相加

        首先看算法题描述:

1、给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

2、请你将两个数相加,并以相同形式返回一个表示和的链表。

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

       看了描述之后,我们能得到的信息是,数字在链表中是逆序存放的,比如我们的数字123,在链表中是3 -> 2 -> 1,这样存放的。其实这样存的好处是显而易见的,这样我们便可以从链表头部开始依次计算。

       首先就是定义链表节点,代码如下:

class ListNode {
   int val;
   ListNode next;
   ListNode(int val) {
      this.val = val;
   }
}

          有了链表定义之后,我们就可以写对应的求和方法了,代码如下:

public ListNode add(ListNode l1, ListNode l2) {
    //定义一个指针指向l1,用于遍历链表l1
    ListNode p1 = l1;
    //定义一个指针指向l2,用于遍历链表l2
    ListNode p2 = l2;
    //定义一个进位的变量(当两个数字相加大于10的时候,就需要进位)
    int carry = 0;
    //定义一个链表用来存储相加后的结果
    ListNode resultNode = new ListNode(-1);
    //定义一个指针cur指向结果链表,用于给结果链表每个节点赋值
    ListNode cur = resultNode;
    //不断遍历两个链表,直到两个链表都遍历完才结束。其中一个链表先遍历完后,就只需要遍历剩下的那//个链表就可以了,先遍历完的那个链表的数字用0来代表。
    while (p1 != null || p2 != null) {
        //链表没有遍历完就取当前遍历到的节点的值,如果已经为null,则赋值为0
        int num1 = p1 != null ? p1.val : 0;
        int num2 = p2 != null ? p2.val : 0;
        //计算两个数字之和,由于可能有进位,因此需要把进位也带上
        int sum = num1 + num2 + carry;
        //计算低位数(如果两个数相加后不超过10,那么就是两数之和,如果超过了10,那么低位就是取个位上的数)
        int low = sum % 10;
        //求和之后需要重新计算进位
        carry = sum / 10;
        //把两数相加的低位数添加到结果链表中
        cur.next = new ListNode(low);
        cur = cur.next;
        //接下来就是遍历两个链表各自下一个节点了,当然,如果p1或p2指针已经指向null了,那么就不用管了,还是null就行
        p1 = p1 != null ? p1.next : p1;
        p2 = p2 != null ? p2.next : p2;
    }
    //由于在while循环中并没有处理最后的进位,如果两个链表最后的数字相加有进位的情况,那么需要把最后的进位也添加到结果链表
    if (carry > 0) {
        cur.next = new ListNode(carry);
    }
    //最后我们只需要返回结果链表即可(由于我们创建结果练笔的时候人为在头部加了一个-1的节点,要跳过它)
    return resultNode.next;
}

           下面我们写个测试方法来测试我们写的方法是否正确

@Test
public void test() {
    //我们定义两个数,存到数组里面,顺序也是逆序,比如我们要计算203+865的和,那么我们定义的两个数组分别如下
    int[] arr1 = {3, 0, 2};
    int[] arr2 = {5, 6, 8};
    //下面我们把两个数组组装到链表当中
    ListNode l1 = new ListNode(-1);
    ListNode cur1 = l1;
    for (int i = 0; i < arr1.length; i++) {
        cur1.next = new ListNode(arr1[i]);
        cur1 = cur1.next;
    }
    ListNode l2 = new ListNode(-1);
    ListNode cur2 = l2;
    for (int i = 0; i < arr2.length; i++) {
        cur2.next = new ListNode(arr2[i]);
        cur2 = cur2.next;
    }
    ListNode result = add(l1.next, l2.next);
    StringBuilder builder = new StringBuilder();
    while (result != null) {
        builder.append(result.val + "  ");
        result = result.next;
    }
    System.out.println(builder.toString());
}

         运行得到的结果:8  6  0  1  

         因为我们的结果链表也是逆序的,因此两数之和1068在链表中就是8 6 0 1,可见我们的结果是正确的,我们写的方法是最优解,简单明了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值