《程序员面试金典》(第六版)习题:仅为记录一下以加强印象,不为商业用途,如有侵权请联系删除。以下源码和解释参考了书中源码以及解释。
算法的基本思想是两个正整数
n
1
n_1
n1和
n
2
n_2
n2相乘等于
n
1
n_1
n1个
n
2
n_2
n2相加(
n
1
<
n
2
n_1<n_2
n1<n2)。如果
n
1
n_1
n1为偶数则可以在累加
n
1
÷
2
n_1\div2
n1÷2个
n
2
n_2
n2后取该累加和的二倍就得到所求的结果(当然这里不是使用的乘法而是两个相同的值相加)。算法使用了递归方法。一个简单的例子如图1所示。
int minProductHelper(int smaller,int bigger)
{
if (smaller == 0)
{
return 0;
}
else if (smaller == 1)
{
return bigger;
}
int s = smaller >> 1;
int side1 = minProductHelper(s,bigger);
int side2 = side1;
if (smaller % 2 == 1)
{
side2= minProductHelper(smaller-s, bigger);
}
return side1 + side2;
}
int minProduct(int a, int b)
{
int bigger = a < b ? b : a;
int smaller = a < b ? a : b;
return minProductHelper(smaller, bigger);
}
改进算法一通过备份计算过的值二减少了重复的计算步骤二提高了时间效率。
//改进算法一
int minProductHelper(int smaller, int bigger,int * memo)
{
if (smaller == 0)
{
return 0;
}
else if (smaller == 1)
{
return bigger;
}
else if (memo[smaller]>0)
{
return memo[smaller];
}
int s = smaller >> 1;
int side1 = minProductHelper(s, bigger, memo);
int side2 = side1;
if (smaller % 2 == 1)
{
side2 = minProductHelper(smaller - s, bigger, memo);
}
memo[smaller]= side1 + side2;
return memo[smaller];
}
int minProduct(int a, int b)
{
int bigger = a < b ? b : a;
int smaller = a < b ? a : b;
int* memo = new int[smaller+1];
return minProductHelper(smaller, bigger,memo);
}
改进算法二通过巧妙的方法消除了实际的smaller参数为奇数(1除外)时的调用也同时消除了改进算法一种对计算步骤的备份。
//改进算法二
int minProductHelper(int smaller,int bigger)
{
if (smaller == 0)
{
return 0;
}
else if (smaller == 1)
{
return bigger;
}
int s = smaller >> 1;
int side1 = minProductHelper(s,bigger);
int side2 = side1;
if (smaller % 2 == 1)
{
return side1 + side2+bigger;
}
else
{
return side1 + side2;
}
}
int minProduct(int a, int b)
{
int bigger = a < b ? b : a;
int smaller = a < b ? a : b;
return minProductHelper(smaller, bigger);
}