从包含0和1的排序数组中计算零数的算法。

时间:2017-03-09 23:15:06

标签: java algorithm

我正在尝试改进算法的运行时间,该算法计算输入数组中的总数0。输入数组的长度为n,由0和1组成,按排序顺序排列。

到目前为止我的算法是:

Algorithm : zeroCount(A)
Input : An sorted array A containing 0s and 1s
Output : total number of 0s in A

if A[0]=1 then 
    return 0;
len <— A.length
if A[len-1]=0 then
    return len
count <— 0
i <—0
for  i<len do           
    if A[i]==0 then 
        count++
    i++
return count

Java实现是:

public int zeroCount(int[] a){

    if(a[0]==1)
    return 0;
    int length =a.length;
    if(a[length-1]==0)
        return length;
    int count=0;
    for(int i=0;i<length&&a[i]==0;i++){
            count++;
    }

    return count;
}

但是,运行时间是O(n)。任何改善此算法运行时间的建议都将受到赞赏。

2 个答案:

答案 0 :(得分:9)

由于输入数组已经排序,因此您可以使用二进制搜索来获得更好的性能。这将运行时间改善为O(log n)。

使用二进制搜索的算法是:

Algorithm : zeroCount(A)
Input : sorted array A containing 0s and 1s
Output : total number of 0s in A

if A[0]=1 then 
    return 0;
len <— A.length
if A[len-1]=0 then
    return len
 return  count(A,0,length)


Algorithm : count(A,lower,upper)
Input :  sorted array A , integers lower and upper 
Output : total number of 0s in A

mid <— (lower+upper) / 2

if A[mid] != A[mid-1] then 
    return mid

if A[mid] != A[mid+1] then
    return mid+1

if A[mid] = 1 then 
    return count(A,lower,mid-1)

if A[mid] = 0 then 
       return count(A,mid+1,upper)

Java实现:

public int zeroCount(int[] a) {

    if (a[0] == 1)    // all are 1
        return 0;
    int length = a.length;
    if (a[length - 1] == 0)   //all are 0
        return length;

    return count(a, 0, length);
}

public int count(int[] a, int lower, int upper) {
    int mid = (lower + upper) / 2;
    if (a[mid] != a[mid - 1])   
        return mid;

    if (a[mid] != a[mid + 1])    
        return mid + 1;

    if (a[mid] == 1) {                // all are 1 above mid 
        return count(a, lower, mid - 1);  
    } else if (a[mid] == 0) {              // all are 0 below mid 
        return count(a, mid + 1, upper);  
    }
    return 0;
}

答案 1 :(得分:3)

您可以调整二进制搜索,以查找数组中最后一次出现(例如,索引i)0。那么0的计数将是(i + 1)。

  int CountOfZeroes(int[] A, int key)
        {
            int low = 0;
            int high = A.size - 1;              
            int result = -1;

            while (low <= high)
            {
                int mid = low + (high-low)/2;

                if (A[mid] == key)
                {
                    result = mid;
                    low = mid + 1;
                }
                else if (key < A[mid])
                {
                    high = mid - 1;
                }
                else 
                {
                    low = mid + 1;
                }
            }

            return result + 1;              
        }

您将在键设置为0的情况下调用上述函数。时间复杂度为O(log n)