最近一段时间一直在做其他事情,今天继续来学习,做了几道代码题,记录一下。 一、快速幂 一般来说,在进行幂运算时,会简单地想成将其连乘。简单的连乘产生的时间复杂度将会是O(n),因为若是n次幂,那么将会执行n次乘运算。但是实际上,还是有优化的余地的。若幂次大于3,比如说 a 4 a^4 a4,实际上可以转化为 a 2 ∗ a 2 a^2 * a^2 a2∗a2进行运算,只需计算一次 a ∗ a a * a a∗a,再计算一次 a 2 ∗ a 2 a^2 * a^2 a2∗a2,总共两次而非原来的四次运算。这样,时间复杂度就降为了O(logn)在更高幂次的计算中效果更佳!因为在平常可以用**pow(x, n)**进行幂次运算,所以如若对性能没有太高要求或是没有特殊应用条件的情况下一般是用不到。但是有些代码题内是会用到的,典型的分治思想。以下为示例代码: double quickMultiply(double x, long long n) { // 初始值设为1,因为幂次为0时,结果为1 double result = 1.0, temp = x; while(n) { /** 将n由十进制作为二进制计算 * 如a^n = a^(2^0) * a^(2^1) * ... * a^(2^n) * a^15 => 15 = 1111, 即 1 * 2^0 + 1 * 2^1 + 1 * 2^2 + 1 * 2^3 * => a^15 = a ^ (2^0 + 2^1 + 2^2 + 2^3) * a^10 = a ^ (0 * 2^0 + 1 * 2^1 + 0 * 2^2 + 1 * 2^3) **/ if(n & 1) { result *= temp; } temp *= temp; n >>= 1; } return result; } 二、快速乘 这个算法思路与快速幂基本一致。不再多做赘述。在做大数(如long long类型)乘法运算时,可能会出现溢出,为了防止这个问题,应用此方法。以下为示例代码 long long quickAdd(long long a, long long b) { long long result = 0, temp = x; while(n) { /** 将n由十进制作为二进制计算 * 如a*b = a*(2^0) + a*(2^1) + ... + a*(2^n) * a*15 => 15 = 1111, 即 1 * 2^0 + 1 * 2^1 + 1 * 2^2 + 1 * 2^3 * => a*15 = a * (2^0 + 2^1 + 2^2 + 2^3) * a*10 = a * (0 * 2^0 + 1 * 2^1 + 0 * 2^2 + 1 * 2^3) **/ if(n & 1) { result += temp; } temp += temp; n >>= 1; } return result; }