《三分钟-算法修行》两数相加之解与应用

简介: 《三分钟-算法修行》两数相加之解与应用

image.png

目录

一、前言

二、题目介绍

三、题目解读

四、通关方式一:人海战术

五、通关方式二:车轮战(递归思想)

六、总结经验

6.1、时间复杂度的推导

6.2、算法思想在实际业务中的运用

七、写在最后

image.png

一、前言

  前两篇给大家介绍关于时间复杂度和空间复杂度的推导逻辑,我们也通过解决"两数求和"问题正式踏入了算法界的修行。 正所谓,一山更比一山难,这次我们遇到的Boss不简单,想要通关就要转动你的小脑筋,时刻留心Boss的"陷阱"。

image.png

二、题目介绍


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



 通关要求: 请你将两个数相加,并以相同形式返回一个表示和的链表。



 通关提示: 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。



 通关示例:

示例1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807
示例2:
输入:l1 = [0], l2 = [0]
输出:[0]
示例3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

image.png

通关提醒:

每个链表中的节点数在范围 [1, 100] 内

0 <= Node.val <= 9

题目数据保证列表表示的数字不含前导零

image.png

三、题目解读


 打蛇打七寸,要解决这个Boss,那就要先找到它的弱点,通过Boss描述,我们会发现它存在以下特点:


链表中的元素都是逆序的,如数值123,则存储在链表中的为:3 - 2 -1


链表中每个元素只能存储一位数,如果元素值相加超过10时,Boss会进化,将值进位给前面的数值,依次类推。 如上图中两个链表第二位元素值分别为4、6,它们相加后会得到10,此时Boss进化,保留0,并向前进位1,所以第三位元素相加则为:3+4+1 = 8。


image.png

四、通关方式一:人海战术


  掌握了Boss的特点,我们能想到的第一个办法就是人海战术,技术Boss再强大,我们也能通过大量的人数来慢慢磨去他的血量,最终,将其击败,下面来看看具体方案:

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        // 链表头元素
        ListNode head = null;
        // 链表最后一个元素
        ListNode tail = null;
        int carry = 0;
        // 如果链表还存在值,则进行两数相加(只要Boss还存活,复活后继续砍)
        while (l1 != null || l2 != null) {
            int l1Val = l1 == null ? 0 : l1.val;
            int l2Val = l2 == null ? 0 : l2.val;
            // 获取链表对应元素之和,如果超过10则进位
            int sum = l1Val + l2Val + carry;
            // 判断是否需要进位
            carry = sum / 10;
            // 设置链表头元素
            if (head == null) {
                head = tail = new ListNode(sum % 10);
            } else {
                tail.next = new ListNode(sum % 10);
                // 将tail永远指向链表的最后一个元素,用于进行下一轮操作
                tail = tail.next;
            }
            // 如果链表还存在值,则进行将元素指向下一个,用于剩下计算
            if (l1 != null) {
                l1 = l1.next;
            }
            if (l2 != null) {
                l2 = l2.next;
            }
        }
        // 如果最后一个元素需要进位,则将则tail指向进位的数值
        if (carry > 0) {
            tail.next = new ListNode(carry);
        }
        return head;
    }

执行结果:

image.png

 果不其然,纵使Boss再强,也耐不过人海战术的无赖,最终Boss还是倒在了强大的玩家脚下。但是,此时又有人抱怨了,通关这个Boss需要花费这么多玩家,玩家人数不够时,能否有其他的方案,只需要少数玩家就可以通关的?



 这时候,足智多谋的小诚想到了一个方案,我们可以借鉴车轮战的思想,将指定人数划分为不同的攻关小分队,不断的去跟Boss磨血量,这样最终也可以将Boss通关,大家也都赞成小诚的想法,下面具体看看如何实现吧。


image.png

五、通关方式二:车轮战(递归思想)

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        // 获取链表中的值
        int l1Val = l1 == null ? 0 : l1.val;
        int l2Val = l2 == null ? 0 : l2.val;
        // 获取链表对应元素之和,如果超过10则进位
        int sum = l1Val + l2Val;
        ListNode node = new ListNode(sum % 10);
        int carry = sum / 10;
        if (l1.next != null || l2.next != null || carry > 0) {
            l1 = l1.next != null ? l1.next : new ListNode(0);
            //这里的new ListCode(0)是因为此时的l1已经完了,l2还没有完,还得用l2的数和l1相加,此时就一直用l1指向一个值为0的节点就可以了。
            l2 = l2.next != null ? l2.next : new ListNode(0);
            l1.val = l1.val + carry;
            // 采用递归思想
            node.next = addTwoNumbers(l1, l2);
        }
        return node;
    }

执行结果:

image.png

image.png

六、总结经验


 上面的两种方案我们都可以解决这个Boss,那它们之间的时间复杂度会存在什么差别?下面来一起推导它们的时间复杂度吧!



6.1、时间复杂度的推导


 通过上面两个方案的代码,我们会发现随着链表元素的增加(问题规模的变大),我们需要循环或者递归的次数也会增多,问题规模和循环或者递归关系是f(n) = n,通过大O计法的推导方式,我们可以得出这两种方案的时间复杂度为:O(max(m,n))。



 说明:max(m,n)表示的是取这两个链表中长度最长的值为输入规模。



6.2、算法思想在实际业务中的运用


 上面的案例中,第一种方案用到了最常见的while循环,这个思想在平常的业务中体现最多的就是数组或者链表键元素的比较,排序(如:冒泡、选择排序等)。



 第二种案例我们采用了递归的思想解决问题,在平常的业务中,这个思想最常见的用途就是查询系统的菜单功能,菜单是层层嵌套的,正好符合了递归的思想。

image.png

七、写在最后


 问题可以是有穷的,但是解决问题的办法确实无穷的,刷leetcode的目的不仅仅是为了应付面试,更多的是为了培养我们遇到问题、解决问题的思考方式。



 一个人可以走得很快,但是一群人才能走得更远!在学习中,抱团是最好的方式,通过互相学习、取长补短,才能够有更快的进步。诚挚邀请您加入【技术圈子】,一起学习、交流、共同成长!


相关文章
|
1月前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
41 3
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的优化算法及其应用
【10月更文挑战第8天】 本文将探讨深度学习中常用的优化算法,包括梯度下降法、Adam和RMSProp等,介绍这些算法的基本原理与应用场景。通过实例分析,帮助读者更好地理解和应用这些优化算法,提高深度学习模型的训练效率与性能。
145 63
|
17天前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
24 0
|
28天前
|
存储 算法 搜索推荐
这些算法在实际应用中有哪些具体案例呢
【10月更文挑战第19天】这些算法在实际应用中有哪些具体案例呢
32 1
|
1月前
|
机器学习/深度学习 人工智能 算法
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
76 0
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
|
1月前
|
算法 安全 物联网
如何应用SM2算法进行身份认证
【10月更文挑战第5天】如何应用SM2算法进行身份认证
62 1
|
1月前
|
存储 算法 安全
SM2算法的应用场景有哪些?
【10月更文挑战第5天】SM2算法的应用场景有哪些?
75 1
|
1月前
|
存储 算法 安全
Python 加密算法详解与应用
Python 加密算法详解与应用
30 1
|
1月前
|
机器学习/深度学习 算法
深度学习中的优化算法及其应用
本文探讨了深度学习中常用的优化算法,包括梯度下降、随机梯度下降、动量方法和Adam方法。通过对比这些算法的优缺点及适用场景,帮助读者更好地理解和应用这些优化方法。
31 2
|
28天前
|
监控 算法 数据挖掘
HyperLogLog算法有哪些应用场景呢
【10月更文挑战第19天】HyperLogLog算法有哪些应用场景呢
15 0
下一篇
无影云桌面