我正在尝试实现一个解决方案,在给定的整数列表中找到第k个最大元素,其中Big-O表示法的平均时间复杂度为O(N*log(N))
,其中N是列表中元素的数量。
根据我的理解,Merge-sort的平均时间复杂度为O(N*log(N))
但是在下面的代码中,我实际上使用了额外的for循环以及mergesort算法来删除重复项,这肯定违反了我的查找规则k O(N*log(N))
的最大元素。如何通过Big-O表示法实现O(N*log(N))
平均时间复杂度来实现它?
public class FindLargest {
public static void nthLargeNumber(int[] arr, String nthElement) {
mergeSort_srt(arr, 0, arr.length - 1);
// remove duplicate elements logic
int b = 0;
for (int i = 1; i < arr.length; i++) {
if (arr[b] != arr[i]) {
b++;
arr[b] = arr[i];
}
}
int bbb = Integer.parseInt(nthElement) - 1;
// printing second highest number among given list
System.out.println("Second highest number is::" + arr[b - bbb]);
}
public static void mergeSort_srt(int array[], int lo, int n) {
int low = lo;
int high = n;
if (low >= high) {
return;
}
int middle = (low + high) / 2;
mergeSort_srt(array, low, middle);
mergeSort_srt(array, middle + 1, high);
int end_low = middle;
int start_high = middle + 1;
while ((lo <= end_low) && (start_high <= high)) {
if (array[low] < array[start_high]) {
low++;
} else {
int Temp = array[start_high];
for (int k = start_high - 1; k >= low; k--) {
array[k + 1] = array[k];
}
array[low] = Temp;
low++;
end_low++;
start_high++;
}
}
}
public static void main(String... str) {
String nthElement = "2";
int[] intArray = { 1, 9, 5, 7, 2, 5 };
FindLargest.nthLargeNumber(intArray, nthElement);
}
}
答案 0 :(得分:1)
这里唯一的问题是你不明白如何进行时间分析。如果你有一个采用O(n)的例程和一个采用O(n * log(n))的例程,那么运行两个例程总共需要O(n * log(n))。因此,您的代码以您想要的方式运行在O(n * log(n))中。
为了正式做事,我们会注意到O()的定义如下: f(x)∈O(g(x))当且仅当存在值c> 0和y使得f(x)<0。 cg(x)每当x&gt;收率
你的合并排序是在O(n * log(n))中,它告诉我们当n> 1时,它的运行时间被c1 * n * log(n)限制在上面。 y1表示某些c1,y1。你的复制消除是在O(n)中,它告诉我们当n> 1时,它的运行时间被c2 * n限制在上面。 y2表示某些c2和y2。使用这个,我们可以知道,当n> 1时,两者的总运行时间在c1 * n * log(n)+ c2 * n之上。 MAX(Y1,Y2)。我们知道c1 * n * log(n)+ c2 * n&lt; c1 * n * log(n)+ c2 * n * log(n)因为log(n)>当然,这简化为(c1 + c2)* n * log(n)。因此,当n> 1时,我们可以知道两者的运行时间在(c1 + c2)* n * log(n)之上。 max(y1,y2)因此,使用c1 + c2作为我们的c和max(y1,y2)作为y,我们知道两者的运行时间在O(n * log(n))。< / p>
非正式地,您可以知道快速增长的函数总是占主导地位,因此如果一段代码是O(n)而第二段是O(n ^ 2),则组合是O(n ^ 2)。如果一个是O(log(n))而第二个是O(n),则组合是O(n)。如果一个是O(n ^ 20)并且第二个是O(n ^ 19.99),则组合是O(n ^ 20)。如果一个是O(n ^ 2000)而第二个是O(2 ^ n),则组合是O(2 ^ n)。
答案 1 :(得分:0)
这里的问题是你的合并例程,你已经使用了另一个循环,我不明白为什么,因此我会说你的合并算法O(n ^ 2)将你的合并排序时间改为O(n ^ 2)。 / p>
这是典型O(N)合并例程的伪代码: -
void merge(int low,int high,int arr[]) {
int buff[high-low+1];
int i = low;
int mid = (low+high)/2;
int j = mid +1;
int k = 0;
while(i<=mid && j<=high) {
if(arr[i]<arr[j]) {
buff[k++] = arr[i];
i++;
}
else {
buff[k++] = arr[j];
j++;
}
}
while(i<=mid) {
buff[k++] = arr[i];
i++;
}
while(j<=high) {
buff[k++] = arr[j];
j++;
}
for(int x=0;x<k;x++) {
arr[low+x] = buff[x];
}
}