我正在从一本书中学习数据结构。在本书中,他们在本章末尾有伪代码片段,我试图确定时间复杂度。我在理解时间复杂度方面遇到了一些困难。
我有两段代码执行相同的操作,查看数组中的元素是否至少发生3次;但是,一个使用递归,另一个使用循环。我有两个答案;谁能告诉我他们是否正确?
第一种方式(没有递归):
boolean findTripleA(int[] anArray) {
if (anArray.length <= 2) {
return false;
}
for (int i=0; i < anArray.length; i++) {
// check if anArray[i] occurs at least three times
// by counting how often it occurs in anArray
int count = 0;
for (int j = 0; j < anArray.length; j++) {
if (anArray[i] == anArray[j]) {
count++;
}
}
if (count >= 3) {
return true;
}
}
return false;
}
我认为第一种方式在最佳和最差情况下的时间复杂度为O(n ^ 2),因为没有办法避免内部for循环。
第二种方式(使用递归):
public static Integer findTripleB(int[] an Array) {
if (anArray.length <= 2) {
return false;
}
// use insertion sort to sort anArray
for (int i = 1; i < anArray.length; i++) {
// insert anArray[i]
int j = i-1;
int element = anArray[i];
while (j >= 0 && anArray[j] > element) {
anArray[j+1] = anArray[j];
j--;
}
anArray[j+1] = element;
}
// check whether anArray contains three consecutive
// elements of the same value
for (int i = 0; i < anArray.length-2; i++) {
if (anArray[i] == anArray[i+2]) {
return new Integer(anArray[i]);
}
}
return null;
}
我认为第二种方式的最坏情况时间复杂度为O(n ^ 2),最好的情况是O(n),如果数组已经排序并且可以跳过插入排序;但我不知道递归是如何生效的。
答案 0 :(得分:0)
第一个最好的情况是O(n) - 考虑当首次出现的元素出现3次时会发生什么(它将在外部循环的一次迭代后返回)。
第二个不使用递归,并且您的运行时间是正确的(技术上插入排序不会被“跳过”,但是已经排序的数组上的插入排序的运行时间是O(n) - 只是制作确定我们在同一页面上。)
解决问题的另外两种方法:
使用更好的sorting algorithm排序,例如mergesort 需要O(n log n)最佳和最差情况。
将元素插入hash map元素中进行计数 将采用预期的O(n)最坏情况,O(1)最佳情况。