0

assume I have sorted array and I want to count the occurrences of element X.

pseudocode:

SET Lo to 1
SET Hi to array length
WHILE Lo <= Hi
  SET Mid to (Lo + Hi) / 2
  IF X < array[Mid] THEN
    SET Hi to Mid - 1
  ELSE IF X > array[Mid] THEN
    SET Lo to Mid + 1
  ELSE 
    RETURN Mid
  ENDIF
ENDWHILE
RETURN -1

now assume I want to find all the occurrences of all numbers in the array but I didn't succeed.

for example - A=[1,1,2,2,2,2,5,5,5] return (1,2),(2,4),(5,3)

the algorithm has to be O(log(n))
help?

john
  • 45
  • 10

3 Answers3

1

Unless the array is very large and contains only few different numbers just do a linear scan through the array. Whenever you detect a change, output the count and reset the counter.

For the problem as currently stated an O(log(n)) algorithm is not possible, since the output of the result takes already O(n) in the worst case no matter how one arrives at it.

Henry
  • 42,982
  • 7
  • 68
  • 84
1

You can do this in O(logn) in best case and O(n*logn) worst case as follow :-

  1. search for index of next greater number (nextind) using modified binary search.
  2. store current,nextind-currentind
  3. currentind = nextind and current = arr[nextind]
  4. do 1 to 3 till you reach the end of array

Time complexity :

O(m*logn) where m is count of unique numbers in array. If m is negligible than it is O(logn)

Vikram Bhat
  • 6,106
  • 3
  • 20
  • 19
0

I'd do something like this:

int nrOfX = 0;
int SortedArray[N];
Lo = 0;
Hi = N-1;
Mid = N-1 div 2;
while (((sortedArray[Lo] < x) or (sortedArray[Hi] > x)) and (Lo != Hi)) {
    if (sortedArray[Mid] < x) {
        Lo = Mid;
    } else if (sortedArray[Mid] > x) {
        Hi = Mid;
    } else if (sortedArray[Mid] == x) {
        Hi = Mid;
        Lo = Mid;
    }
    Mid = (Lo + Hi) div 2;
}
while (sortedArray [Lo - 1] == x) {
    Lo--;
}
while (sortedArray [Hi + 1] == x) {
    Hi++;
}
if (sortedArray[Lo] == x) {
    return ((Hi - Lo) + 1);
} else {
    return 0;
}

Haven't tested it, so you might have to tweak it a bit to get it to work, but the general idea is that you first get Lo and Hi to a x value and from there expand them in different directions allong the array. If x doesn't show up at all, you'll end up with Lo == Hi and since sortedArray[Lo] == 0 this function will return 0. This should run in about O(log N) if #x in array is low. However, this is only useful to find the nr of occurences of 1 particular number, that is x. If you want to know this for all numbers you will get O(N) in worst case, since you'll have to inspect every number when they all differ.

SubliemeSiem
  • 1,129
  • 17
  • 25