面试 | 递归乘法【细节决定成败】
创始人
2024-05-26 16:45:12
0

在这里插入图片描述

不用[ * ]如何使两数相乘❓

  • 一、题目明细
  • 二、思路罗列 & 代码解析
    • 1、野蛮A * B【不符合题意】
    • 2、sizeof【可借鉴】
      • 解析
    • 3、简易递归【推荐】
      • ① 解析(递归展开图)
      • ② 时间复杂度分析
    • 4、移位<<运算【有挑战性💪】
      • ① 思路顺理
      • ② 算法图解
      • ③ 代码分析
      • ④ 调试分析
    • 📺视频解说
  • 三、总结与提炼

一、题目明细

原题传送门

在这里插入图片描述

  • 可能有读者会说为什么那么简单的题目也要写个题解?
  • 答:细节决定成败,不可忽视细枝末节,对算法题的思考尽量要做到多维度考虑、多思考,继而找出最优解👑

二、思路罗列 & 代码解析

下面会列出我所AC的所有解,有些可能不符合题意

1、野蛮A * B【不符合题意】

本以为不让使用【*】运算符,但是试了一下,竟然也可以过😮

int multiply(int A, int B){return A * B;
}

在这里插入图片描述

2、sizeof【可借鉴】

这个方法我觉得还是比较巧妙,如果题目没有指定说要使用递归来进行求解,可以考虑

int multiply(int A, int B){char a[A][B];return sizeof(a);
}

在这里插入图片描述

解析

  • 有很多学习完C语言的同学在使用sizeof()的时候都会觉得它是一个函数,但真的是吗?其实可以去cpluplus中看看。就可以观测到无论是搜索多久都不会有结果

在这里插入图片描述

  • 其实对于sizeof()来说是一个操作符,而且是一个单目操作符,如果不清楚的可以看看我的操作符汇总大全。用来计算某一个数据类型的变量所占的字节大小。不要和Pascal中的sizeof()混淆了,在这门语言中是作为【函数】来看待的

Pascal 语言中,sizeof() 是一种内存容量度量函数,功能是返回一个变量或者类型的大小(以字节为单位);在 C语言中,sizeof() 是一个判断数据类型或者表达式长度的运算符《来源于百度百科》


  • 所以在这道题中,其实我们利用两数相乘的这个逻辑,去定义一个字符型的二维数组,然后将这个数组当做是长方体,那对于长方体的面积来说就是长 * 宽,那对于二维数组这个矩阵来说其实就是去计算它在内存中所占地字节数是多少,这样就可以很轻易地想到使用sizeof()去进行求解
  • 这里要注意的是需定义为【字符数组】,因为char类型的变量在内存中只占一个字节,若是定义为整型数组,算出来就是结果的4倍了!

在这里插入图片描述

3、简易递归【推荐】

这才是最符合题意的做法,使用递归去进行求解

class Solution {
public:int Mul(int big, int small){if(small == 0)  return 0;         //与0相乘一定为0if(small == 1)  return big;       //与1相乘一定为自身return big + Mul(big, small - 1);   //small个big相加,small递减}int multiply(int A, int B) {//首先区分两者中的大的那个和小的那个int big = A > B ? A : B;int small = A < B ? A : B;return Mul(big, small);}
};

在这里插入图片描述

① 解析(递归展开图)

递归对有些同学来说可能不好理解,因此讲说一下代码逻辑

  • 首先题目说到,两个数相乘不可以使用【*】号,那其实我们其看一下两个数相乘的原理也就是从加法转化过来的,例1:3 * 4 == 4 + 4 + 4 | 例2:2 * 5 == 5 + 5
  • 选取到小的那个数作为相加的次数
  • 选取大的那个数作为相加的数字

  • 在递归的函数中,若是发现small == 0,那直接return 0即可,因为任何数和0相乘都是0
  • 若是发现small == 1,那就直接返回big,因为任何数和1相乘都是1
  • 若是都不满足,则进行递归调用,注意要保留当前层的big,然后再产生递归让small - 1即可

若是感觉有点抽象的话,就通过递归展开图来看看吧
在这里插入图片描述

② 时间复杂度分析

  • 对于上面这种方法的时间复杂度为O(N)。准确点来说是O(small),相当于一个线性阶。如果对时间复杂度如何计算不是很懂,可以看看我的这篇文章——> 时间与空间复杂度就看这篇了
  • 那有没有更优的方法呢?就来看看下面这种吧

4、移位<<运算【有挑战性💪】

若是你搞懂了上面这种方法,那便来看看这种移位<<这种方法吧,会让你更上一层楼

int Mul(int big, int small)
{if(small == 0)  return 0;if(small == 1)  return big;int half_small = small >> 1;    //右移运算符,每次使small缩小一半//递归算出每一半的乘积int half_Sum = Mul(big, half_small);    //判断每一层的递归中的small为偶数还是奇数if(small % 2 == 0){return half_Sum + half_Sum;     //若为偶数直接是double倍}else{return half_Sum + half_Sum + big;   //若为奇数则还需加上一个big}
}int multiply(int A, int B){//1.划分二者的大小int big = A > B ? A : B;int small = A < B ? A :B;int ret = Mul(big, small);return ret;
}

在这里插入图片描述

① 思路顺理

  • 首先对于主接口函数还是一样,区分两者中谁大谁小,然后传入递归函数中
  • 在递归函数中,我的思路是这样的,既然在上一题中想到了线性阶,那便想要优化为对数阶,那对于对数阶而言一定存在一个二分的关系,然后就可以想到一半的关系
  • 所以对于small个big相乘,其实并不需要加small次,加small/2次即可,对于small/2次,其实也只需要加small/2次即可,那么这就相当于是一个递归的问题,要求出8个10的和,先求出4个10的和;要求出4个10的和,先求出2个10的和,要求出2个10的和,就先求出1个10,最后再进行层层回调,便可以算出small个big的和为多少了
  • 不过这个small的情况还是判断其为奇数还是偶数:对于偶数来说就是一个二分,但是对于奇数来说就不一样了,因为÷2之后相当于是一个整除,所以会漏掉一次的big相加,要在求当前和的最后加上一个big
  • 对于上述这种算法的时间复杂度很明显可以看出来是O(log2small)

② 算法图解

经过思路的讲解与分析,可能你还有些云里雾里😵那就通过算法分解图来看看吧

  • small为偶数的情况

在这里插入图片描述

  • small为奇数的情况

在这里插入图片描述

③ 代码分析

通过算法图的展示之后,相信你一定很清楚该如何去解决这个问题了,我们再来回顾一下代码

  • 若是small进来直接为0,那么直接return 0便可
if(small == 0)  return 0;
  • 这句便是算出当前层small的一半为多少,使用的便是移位运算符,右移是缩小1/2
int half_small = small >> 1;    //右移运算符,每次使small缩小一半
  • 求出当前层small的一半之后,就继续进行递归,
//递归算出每一半的乘积
int half_Sum = Mul(big, half_small); 
  • 若是当递归调用的时候small == 1了,便return big进行回调
if(small == 1)  return big;
  • 在回调之后,便会进行当前层一半总数的计算,这里就是我说的要对small进行奇偶数分类的情况
//判断每一层的递归中的small为偶数还是奇数
if(small % 2 == 0){return half_Sum + half_Sum;     //若为偶数直接是double倍
}else{return half_Sum + half_Sum + big;   //若为奇数则还需加上一个big
}

④ 调试分析

通过调试再来看看程序到底是如何运行的

  • big = 6, small = 4为例,进到递归函数中

在这里插入图片描述

  • 通过右移运算符>>便算出small的一半

在这里插入图片描述

  • 继续递归,直到small == 1为止

在这里插入图片描述

  • 此时small便为1,执行return big

在这里插入图片描述

  • 递归回来之后便计算当前层的总和,因为small == 2为偶数所以无需再加上big

在这里插入图片描述

  • 此时继续回调,算出small == 4这一层的总和

在这里插入图片描述

  • 最后便通过递归计算出了【4 * 6】的和为24

在这里插入图片描述


为了更好地对照算法图,也来测试一下奇数的情况

  • 这次的对比是运算是big = 8, small = 6

在这里插入图片描述

  • 可以看到,出现了small为奇数的情况

在这里插入图片描述

  • 继续递归,直到small == 1为止

在这里插入图片描述

  • 然后开始计算每一层的总和,注意:回到small == 3的递归层时,要进入第二个if分支

在这里插入图片描述

  • 此时就需要加上整除之后遗漏的那个big了

在这里插入图片描述

  • 回到small == 6的递归层时继续计算当前层的总和

在这里插入图片描述

  • 最后就算出了6 * 8 = 48的结果

在这里插入图片描述

📺视频解说

本文的题解都是通过看下面这位UP主写出来的,可以看看他的讲解——> 主页

leetcode 面试题 08.05. 递归乘法

三、总结与提炼

最后来总结一下本文所学习的内容📖

  • 【递归乘法】这道题是LeetCode上的一道面试题,虽然题目看起来比较简单,但是递归对很多同学来说还是比较困难,所以我在这里做一个细致的讲解
  • 主要是详细解说了有关递归的两种解法,对于简易递归来说就是本题的答案,但是我们要像在面试中胜出,就必须要想到更好、更优的解法;对于第二种sizeof的解法,可供读者参考,也是比较巧妙的方法,不过要清楚sizeof是一个操作符,而不是一个函数

学会不断思考,不断突破自己,才是最大的进步

在这里插入图片描述

相关内容

热门资讯

安卓系统的经典铃声,唤醒回忆的... 你有没有发现,手机里那些熟悉的铃声,有时候就像老朋友一样,陪伴着我们度过了无数个日日夜夜?今天,就让...
鸿蒙系统还是安卓系统号,系统之... 你有没有想过,手机里的操作系统就像是我们的大脑,它决定了我们手机能做什么,不能做什么。现在,就让我们...
安卓系统装贝达,安卓系统下的贝... 你有没有想过,你的安卓手机装上贝达系统后,会有怎样的奇妙体验呢?想象你的手机瞬间变身,变得流畅无比,...
安卓系统沃尔沃音响设置,轻松享... 你有没有发现,自从你的安卓手机和沃尔沃音响完美结合后,开车时的音乐体验简直就像是在音乐厅里一样?没错...
米10系统基于安卓,基于安卓的... 你知道吗?最近手机圈里可是热闹非凡呢!小米10这款手机,自从发布以来就吸引了无数人的目光。而它所搭载...
命令安卓系统怎么卸载,安卓系统... 手机里装了太多不用的应用,是不是感觉手机都快要爆炸了?别急,今天就来教你怎么轻松卸载安卓系统中的应用...
安卓系统安装小学教材,安卓系统... 你有没有想过,手机里的安卓系统竟然能装上小学教材呢?没错,你没听错!在这个信息爆炸的时代,科技的发展...
华为安卓系统锁住了,揭秘锁屏背... 最近是不是发现你的华为手机有点儿“顽皮”了?它突然间变得神秘起来,屏幕上那个熟悉的安卓系统仿佛被施了...
安卓电脑改苹果系统,跨越平台的... 你有没有想过,把你的安卓电脑改头换面,变成一个优雅的苹果系统使用者呢?想象那流畅的界面,那独特的触控...
安卓系统怎么按后台,并在任务完... 你有没有遇到过这种情况:手机屏幕一黑,安卓系统就自动进入后台了?是不是觉得有点小郁闷,想要手动切换回...
2021年安卓系统ui,202... 你有没有发现,手机界面最近好像换了个模样?没错,2021年的安卓系统UI可是来了一场大变身呢!今天,...
安卓系统程序编写软件,打造个性... 你有没有想过,手机里的那些神奇应用是怎么诞生的呢?没错,就是那些让你在闲暇时光刷刷视频、在通勤路上玩...
自动开机安卓系统,智能生活新篇... 你有没有想过,当你的安卓手机在清晨的第一缕阳光照耀下自动开机,那种轻松自在的感觉?想象不用再手动解锁...
真我平板x安卓系统,畅享智能生... 亲爱的读者们,你是否也在寻找一款既能满足你对平板电脑的期待,又能让你畅享安卓系统带来的无限乐趣的设备...
恒星安卓系统官网,引领未来智能... 亲爱的读者们,你是否曾好奇过那些闪耀在夜空中的星星,它们是如何在浩瀚的宇宙中熠熠生辉的呢?今天,我要...
u8安卓系统,功能与特色深度解... 你知道吗?在手机操作系统界,有一个小家伙可是相当受欢迎的,它就是U8安卓系统。今天,就让我带你来一探...
花椒安卓系统美颜功能,打造完美... 你有没有发现,现在拍照已经不仅仅是记录生活的工具了,它更是一种艺术创作呢!而在这其中,花椒安卓系统的...
戴尔平板升级安卓系统,畅享安卓... 你有没有发现,戴尔平板最近好像悄悄地来了一次大变身?没错,就是那个我们熟悉的戴尔平板,它现在竟然可以...
安卓助手怎么升级系统,畅享最新... 亲爱的安卓用户们,你是否也和我一样,对安卓系统的升级充满了期待和好奇呢?每次系统升级,都仿佛是给我们...
国产安卓系统的发展,国产安卓系... 你知道吗?在我国科技飞速发展的今天,国产安卓系统可是越来越受到大家的关注呢!它就像一颗冉冉升起的新星...