我正在尝试为我的项目改进算法。而不是将数组划分为2部分我计划在log(n)和剩余部分(即(logn-1)(n / logn))中划分数组。例如: 对于n = 64 的log(n)= 6 我将通过数组并以这样的方式划分它,使得一部分将包含logn = 6而其他部分将具有剩余的(64-6)= 58元素,并且我将递归地执行6和58,直到我得到2.即在下一个传递中,我将在logn = 5和53元素中除以58,对于6,我将它分为log n = 2,其他部分将有4个元素。
到底会有什么时间复杂?我会得到nlogn但是那会是什么常数因素?任何人都能帮我找到与nlogn不变的因素吗?
答案 0 :(得分:1)
看看你的例子:
n=64 log(n)=6
似乎你的意思是log2(n)(不是log10(n))。
由于n的数量是整数,对于使用2 ^ n作为分频器的这种计算,最好使用右按位移位运算符(也就是说,在大多数语言中,它看起来像这个:>>)您可以考虑使用它来加速计算。
通过这种方式,您可以更快地将阵列拆分为2.使用您的配方。
现在回答你的问题。如果您根本使用数组元素的这种划分,时间复杂度可能会降低,也可能不会降低,具体取决于所讨论的算法。
例如,如果算法是x数之间的简单加法。通过递归地将其划分为更小的数组,它不会降低复杂性。相反,它会增加时间复杂性。
但是如果你的算法是基于n元素排序的话,那么数组的递归划分可能是个好主意。在这种情况下,它可以降低复杂性,因为算法中的数量或元素决定了操作的数量。
因此,底线来了解这里的复杂性是算法的样子,而不是如何将算法的元素递归分为2或递归到log2(n)。
答案 1 :(得分:1)
具有这种除法的算法的复杂性由这种递归关系表示:
T(n) = T(n - log(n)) + T(log(n)) + D(n)
其中D(n)
是" merge"的复杂性。步骤
要在此复杂性上创建渐近下界,请首先注意第二项T(log(n))
非常小。我们可以在进一步的分析中忽略它,并且仍然可以获得相当准确的下限估计值。
至于第一个词T(n - log(n))
,我们可以注意到总和
log(n) + log(n -log(n)) + log(n-log(n)-log(n-log(n))) + ... (k terms in total)
小于k log(n)
。要通过反复从n
中减去log(n)
来将k = n / log(n)
减少为零,必须采取n / log(n)
步骤。因此,D(n/2)
步的平均大小n
(因为输入大小从0
到D(n) = O(n)
不等;平均而言,输入大小是原始输入大小的一半)
现在让我们考虑一个具体的例子。假设D(n/2) = O(n)
与快速排序或合并排序一样,O(n / log(n)) O(n) = O(n^2 / log n)
也是如此,总复杂度为O(n log n)
。
简而言之,这种划分方法并不是很好:它将// init
var obj={};
var max=0,maxName="";
var x={};
for(var key in window){
x[key]=window[key];
}
// your code
a = 55;
b = 13;
c = 45;
d = 5;
// end of your code
// select the max num
for(var key in window){
if(typeof(window[key]) == "number" && typeof(x[key])!="number"){
if(window[key]>max){
max=window[key];
maxName=key;
}
}
}
// output the variable name
console.log(maxName);
复杂度的算法转换为几乎二次复杂度的算法。