2.Add Two Numbers

题目描述:中等难度
在这里插入图片描述
就是两个链表表示的数相加,这样就可以实现两个很大的数相加了,无需考虑数值 intfloat 的限制了。
在这里插入图片描述
链表最左边表示个位数,代表 342 + 465 =807

思路

首先每一位相加肯定会产生进位,我们用 carry 表示。进位最大会是 1 ,因为最大的情况是无非是 9 + 9 + 1 = 19 ,也就是两个最大的数相加,再加进位,这样最大是 19 ,不会产生进位 2 。下边是伪代码。

  • 初始化一个节点的头,dummy head ,但是这个头不存储数字。并且将 cur 指向它。
  • 初始化进位 carry 为 0 。
  • 初始化 pq 分别为给定的两个链表 l1l2 的头,也就是个位。
  • 循环,直到 l1l2 全部到达 null 。
  • 设置 xp 节点的值,如果 p 已经到达了 null,设置 x0
  • 设置 yq 节点的值,如果 q 已经到达了 null,设置 y0
  • 设置 sum = x + y + carry
  • 更新 carry = sum / 10
  • 创建一个值为 sum mod 10的节点,并将 currnext 指向它,同时 curr 指向变为当前的新节点。
  • 向前移动 pq
  • 判断 carry 是否等于 1 ,如果等于 1 ,在链表末尾增加一个为 1 的节点。
  • 返回 dummy headnext ,也就是个位数开始的地方。

初始化的节点 dummy head 没有存储值,最后返回 dummy headnext 。这样的好处是不用单独对 head 进行判断改变值。也就是如果一开始的 head 就是代表个位数,那么开始初始化的时候并不知道它的值是多少,所以还需要在进入循环前单独对它进行值的更正,不能像现在一样只用一个循环简洁。

代码如下所示:

class ListNode{
    int val;
    ListNode next;
    ListNode(int x){val=x;}
}
public class Add_Two_Numbers {
    public static ListNode addTwoNumbers(ListNode l1,ListNode l2){
        ListNode dummyHead = new ListNode(0);
        ListNode p = l1;
        ListNode q = l2;
        ListNode cur = dummyHead;

        int carry = 0;
        while(p!=null || q!=null){
            int x = (p!=null) ? p.val:0;
            int y = (q!=null) ? q.val:0;
            int sum = carry+x+y;
            carry=sum/10;
            cur.next=new ListNode(sum % 10);
            cur=cur.next;
            if(p!=null) p=p.next;
            if(q!=null) q=q.next;
        }
        return dummyHead.next;
    }
    public static void main(String args[]){
        ListNode l1=new ListNode(2);
        ListNode p=l1;
        p.next=new ListNode(4);
        p=p.next;
        p.next=new ListNode(3);

        ListNode l2=new ListNode(5);
        ListNode q=l2;
        q.next=new ListNode(6);
        q=q.next;
        q.next=new ListNode(4);
        ListNode ans = addTwoNumbers(l1,l2);
        while(ans!=null){
            System.out.println(ans.val);
            ans=ans.next;
        }
    }
}

这里有一个需要注意的点就是

if (carry > 0) {
        curr.next = new ListNode(carry);
    }

为什么要添加这个条件:
举个例子L1=[5],L2=[5],最终cur加入的是(5+5)%10=0,还需要把1加进去。

  • 时间复杂度:O(max(m,n)),m 和 n 代表 l1 和 l2 的长度。

  • 空间复杂度:O(max(m,n)),m 和 n 代表 l1 和 l2 的长度。而其实新的 List 最大长度是 O(max(m,n))+ 1,因为我们的 head 没有存储值。

参考文献
  • https://zhuanlan.zhihu.com/p/41948568
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安替-AnTi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值