我有一个问题要回答我们能想到的最好的复杂性。
我们得到了一个排序数组(int)和X值。我们需要做的就是找出数组中有多少位数等于X值。
这是我对这种情况的解决方案,因为我对复杂性了解不多。 我所知道的是更好的方法没有for循环:X
class Question
{
public static int mount (int [] a, int x)
{
int first=0, last=a.length-1, count=0, pointer=0;
boolean found=false, finish=false;
if (x < a[0] || x > a[a.length-1])
return 0;
while (! found) **//Searching any place in the array that equals to x value;**
{
if ( a[(first+last)/2] > x)
last = (first+last)/2;
else if ( a[(first+last)/2] < x)
first = (first+last)/2;
else
{
pointer = (first+last)/2;
count = 1;
found = true; break;
}
if (Math.abs(last-first) == 1)
{
if (a[first] == x)
{
pointer = first;
count = 1;
found = true;
}
else if (a[last] == x)
{
pointer = last;
count = 1;
found = true;
}
else
return 0;
}
if (first == last)
{
if (a[first] == x)
{
pointer = first;
count = 1;
found = true;
}
else
return 0;
}
}
int backPointer=pointer, forwardPointer=pointer;
boolean stop1=false, stop2= false;
while (!finish) **//Counting the number of places the X value is near our pointer.**
{
if (backPointer-1 >= 0)
if (a[backPointer-1] == x)
{
count++;
backPointer--;
}
else
stop1 = true;
if (forwardPointer+1 <= a.length-1)
if (a[forwardPointer+1] == x)
{
count++;
forwardPointer++;
}
else
stop2 = true;
if (stop1 && stop2)
finish=true;
}
return count;
}
public static void main (String [] args)
{
int [] a = {-25,0,5,11,11,99};
System.out.println(mount(a, 11));
}
}
打印命令计算正确并打印“2”。
我只是想知道是否有人可以考虑这种方法更好的复杂性。
此外,我怎么知道方法的时间/空间复杂度是什么?
我所知道的时间/空间复杂性是for循环是O(n)。我不知道如何计算我的方法复杂性。
非常感谢!
编辑: 这是更改后的第二个while循环:
while (!stop1 || !stop2) //Counting the number of places the X value is near our pointer.
{
if (!stop1)
{
if ( a[last] == x )
{
stop1 = true;
count += (last-pointer);
}
else if ( a[(last+forwardPointer)/2] == x )
{
if (last-forwardPointer == 1)
{
stop1 = true;
count += (forwardPointer-pointer);
}
else
forwardPointer = (last + forwardPointer) / 2;
}
else
last = ((last + forwardPointer) / 2) - 1;
}
if (!stop2)
{
if (a[first] == x)
{
stop2 = true;
count += (pointer - first);
}
else if ( a[(first+backPointer)/2] == x )
{
if (backPointer - first == 1)
{
stop2 = true;
count += (pointer-backPointer);
}
else
backPointer = (first + backPointer) / 2;
}
else
first = ((first + backPointer) / 2) + 1;
}
}
您如何看待变化?我认为它会将时间复杂度改为O(long(n))。
答案 0 :(得分:0)
首先让我们检查你的代码:
代码可以进行大量重构和清理(这也可以实现更高效的实现,但没有提高时间或空间复杂度),但算法本身非常好。
它的作用是使用标准二进制搜索来查找具有所需值的项目,然后扫描到后面和前面以查找值的所有其他出现。
就时间复杂度而言,算法 O(N)。最糟糕的情况是整个数组的值相同,最后在第二阶段迭代所有数组(二进制搜索只需要1次迭代)。空间复杂度 O(1)。内存使用量(空间)不受输入大小增长的影响。
如果继续在2个子阵列(后面和前面)上使用二进制搜索并以这种方式对数增加“匹配范围”,则可以改善最坏情况时间复杂度。时间复杂度将变为 O(log(N))。由于与以前相同的原因,空间复杂性将保持 O(1)。
但是,真实场景(阵列包含各种值)的平均复杂度非常接近,甚至可能倾向于您自己的版本。