Java 使用二进制搜索在排序列表中查找重复项的while循环的时间复杂度是多少?

Java 使用二进制搜索在排序列表中查找重复项的while循环的时间复杂度是多少?,java,algorithm,data-structures,time-complexity,complexity-theory,Java,Algorithm,Data Structures,Time Complexity,Complexity Theory,我想知道函数复制的时间复杂度是多少,因为我认为它是O(nlogn)由于使用了二进制搜索算法,同时实现了while循环,以搜索数组中第一个实例位置的左右两侧,在该位置找到值,以查看其是否在排序数组中重复。我想知道它是否O(logn),因为我认为while循环实际上并不是在所有元素中循环,只是在我们正在搜索的值附近的元素,以查看它是否重复。如果不是的话,我希望您能给我一些建议,让它O(logn) public class Problem2 { public static void main

我想知道函数复制的时间复杂度是多少,因为我认为它是O(nlogn)由于使用了二进制搜索算法,同时实现了while循环,以搜索数组中第一个实例位置的左右两侧,在该位置找到值,以查看其是否在排序数组中重复。我想知道它是否O(logn),因为我认为while循环实际上并不是在所有元素中循环,只是在我们正在搜索的值附近的元素,以查看它是否重复。如果不是的话,我希望您能给我一些建议,让它O(logn)

public class Problem2 {

    public static void main(String[] args) {
        
        int[] arrayA = {-1, 2, 3, 5, 6, 6, 6, 9, 10};
        
        int repeatedValue = 6;
        
        System.out.println(duplicates(arrayA, repeatedValue));
    }
    
    public static int duplicates(int[] a, int x){
        
        int counter = 0;                 //counter for duplicates.
        int index = binarySearch(a, x);  // index = 4 where x is.
        int leftIndex = index - 1;       // leftIndex = 3
        int rightIndex = index + 1;      // rightIndex = 5
        
        //Condition incase value does not exist.
        if(index == -1)
            return -1;
        
        //While loop to check left and right side of index for duplicates.
        while(a[leftIndex] == x || a[rightIndex] == x){
            
            if(a[leftIndex] == x){
                counter++;
                leftIndex--;
                
            }
            else if(a[rightIndex] == x){
                counter++;
                rightIndex++;
                
            }
           
        }
        
        //returning the counter plus one because we did not count the first instance
        //when it was searched.
        return counter + 1;
    }
    
    public static int binarySearch(int[] a, int x){
        
        int low = 0, high = a.length - 1;
        
        while(low <= high){
            
            int mid = (low + high) / 2;
            
            if(a[mid] < x)
                low = mid + 1;
            else if(a[mid] > x)
                high = mid - 1;
            else
                return mid;
        }
        return -1;
    }
}
公共类问题2{
公共静态void main(字符串[]args){
int[]arrayA={-1,2,3,5,6,6,6,9,10};
int repeatedValue=6;
System.out.println(副本(arrayA,repeatedValue));
}
公共静态整数重复项(int[]a,int x){
int counter=0;//重复的计数器。
int index=binarySearch(a,x);//index=4,其中x是。
int leftIndex=index-1;//leftIndex=3
int rightIndex=index+1;//rightIndex=5
//条件incase值不存在。
如果(索引==-1)
返回-1;
//While循环检查索引的左侧和右侧是否存在重复项。
while(a[leftIndex]==x | | a[rightIndex]==x){
if(a[leftIndex]==x){
计数器++;
左索引--;
}
如果(a[rightIndex]==x)为else{
计数器++;
rightIndex++;
}
}
//返回计数器加1,因为我们没有计算第一个实例
//当它被搜查时。
返回计数器+1;
}
公共静态int二进制搜索(int[]a,int x){
int低=0,高=a。长度-1;
while(低x)
高=中-1;
其他的
中途返回;
}
返回-1;
}
}
这不是
O(n*logn)
因为你没有对每个二进制搜索进行线性搜索:你在进行线性搜索和二进制搜索

I是
O(logn)
还是
O(n)
,取决于目标号码的重复数量。由于
O(n)
大于
O(logn)
,最坏情况下的复杂性是
O(n)

要更多地了解您的平均案例复杂性,我们需要知道平均案例输入是什么样子的

如果大小为
n
(您实际搜索的)的列表中的平均重复数低于
logn
,则您将具有
O(logn)
平均案例复杂度

关于如何制作的建议
O(logn)

要进行二进制搜索,您已经在对输入执行预计算步骤,即对数组进行排序

将预计算步骤更改为不仅对阵列进行排序,还对阵列进行重复数据消除,并将每个唯一数字的重复数存储在单独的阵列中

然后搜索算法变为:

  • 二进制搜索目标号码的正确索引
  • 使用在步骤1中找到的索引,从具有重复计数的单独数组中返回该数字的重复数
  • 只有在同一输入数据上搜索许多不同的目标编号时,这才有意义。

    这不是
    O(n*logn)
    ,因为你不是对每个二进制搜索都进行线性搜索:你在进行线性搜索和二进制搜索

    I是
    O(logn)
    还是
    O(n)
    ,取决于目标号码的重复数量。由于
    O(n)
    大于
    O(logn)
    ,最坏情况下的复杂性是
    O(n)

    要更多地了解您的平均案例复杂性,我们需要知道平均案例输入是什么样子的

    如果大小为
    n
    (您实际搜索的)的列表中的平均重复数低于
    logn
    ,则您将具有
    O(logn)
    平均案例复杂度

    关于如何制作的建议
    O(logn)

    要进行二进制搜索,您已经在对输入执行预计算步骤,即对数组进行排序

    将预计算步骤更改为不仅对阵列进行排序,还对阵列进行重复数据消除,并将每个唯一数字的重复数存储在单独的阵列中

    然后搜索算法变为:

  • 二进制搜索目标号码的正确索引
  • 使用在步骤1中找到的索引,从具有重复计数的单独数组中返回该数字的重复数

  • 只有当您在同一输入数据上搜索许多不同的目标编号时,这才有意义。

    我这里肯定遗漏了什么。要进行二进制搜索,必须对列表进行排序。如果已排序,则重复项将相邻。除了遍历列表并将每个元素与其前一个元素进行比较,在O(n)时间内查找所有重复项之外,您为什么还要做其他事情呢?目标是设计一个O(logn)算法,用于查找重复项并计算排序数组中的频率,但在尝试之前,我试着按照我最初的想法来做,即使用二进制搜索来查找第一个值实例的索引,我想检查它是否重复。因此,一旦我有了那个索引,我就在while循环中使用它作为参考,使用leftIndex和rightdex检查相邻的两个边,这听起来很正常