原题传送门
下面会列出我所AC的所有解,有些可能不符合题意
本以为不让使用【*】运算符,但是试了一下,竟然也可以过
int multiply(int A, int B){
return A * B;
}
这个方法我觉得还是比较巧妙,如果题目没有指定说要使用递归
来进行求解,可以考虑
int multiply(int A, int B){
char a[A][B];
return sizeof(a);
}
sizeof()
的时候都会觉得它是一个函数,但真的是吗?其实可以去cpluplus中看看。就可以观测到无论是搜索多久都不会有结果sizeof()
来说是一个操作符,而且是一个单目操作符,如果不清楚的可以看看我的操作符汇总大全。用来计算某一个数据类型的变量所占的字节大小。不要和Pascal中的sizeof()混淆了,在这门语言中是作为【函数】来看待的在 Pascal 语言中,sizeof() 是一种内存容量度量函数,功能是返回一个变量或者类型的大小(以字节为单位);在 C语言中,sizeof() 是一个判断数据类型或者表达式长度的运算符《来源于百度百科》
长 * 宽
,那对于二维数组这个矩阵来说其实就是去计算它在内存中所占地字节数是多少,这样就可以很轻易地想到使用sizeof()
去进行求解char
类型的变量在内存中只占一个字节,若是定义为整型数组,算出来就是结果的4倍了!这才是最符合题意的做法,使用递归去进行求解
class Solution {
public:
int Mul(int big, int small)
{
if(small == 0) return 0; //与0相乘一定为0
if(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相乘都是0small == 1
,那就直接返回big,因为任何数和1相乘都是1small - 1
即可O(N)
。准确点来说是O(small)
,相当于一个线性阶。如果对时间复杂度如何计算不是很懂,可以看看我的这篇文章——> 时间与空间复杂度就看这篇了若是你搞懂了上面这种方法,那便来看看这种
移位<<
这种方法吧,会让你更上一层楼
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/2
次即可,对于small/2次,其实也只需要加small/2
次即可,那么这就相当于是一个递归的问题,要求出8个10的和,先求出4个10的和;要求出4个10的和,先求出2个10的和,要求出2个10的和,就先求出1个10,最后再进行层层回调,便可以算出small个big的和为多少了所以会漏掉一次的big相加
,要在求当前和的最后加上一个big
经过思路的讲解与分析,可能你还有些云里雾里那就通过算法分解图来看看吧
通过算法图的展示之后,相信你一定很清楚该如何去解决这个问题了,我们再来回顾一下代码
return 0
便可if(small == 0) return 0;
右移是缩小1/2
int half_small = small >> 1; //右移运算符,每次使small缩小一半
//递归算出每一半的乘积
int half_Sum = Mul(big, half_small);
small == 1
了,便return big
进行回调if(small == 1) return big;
//判断每一层的递归中的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
为止return big
small == 2
为偶数所以无需再加上bigsmall == 4
这一层的总和为了更好地对照算法图,也来测试一下奇数的情况
big = 8, small = 6
small
为奇数的情况small == 1
为止small == 3
的递归层时,要进入第二个if分支small == 6
的递归层时继续计算当前层的总和6 * 8 = 48
的结果本文的题解都是通过看下面这位UP主写出来的,可以看看他的讲解——> 主页
leetcode 面试题 08.05. 递归乘法
最后来总结一下本文所学习的内容
sizeof
的解法,可供读者参考,也是比较巧妙的方法,不过要清楚sizeof是一个操作符,而不是一个函数学会不断思考,不断突破自己,才是最大的进步