2

I was recently asked this question in an interview for which i could give an O(nlogn) solution, but couldn't find a logic for O(n) . Can someone help me with O(n) solution?

In an array find the length of longest sequence of numbers

Example : Input : 2 4 6 7 3 1 Output: 4 (because 1,2,3,4 is a sequence even though they are not in consecutive positions)

The solution should also be realistic in terms of space consumed . i.e the solution should be realistic even with an array of 1 billion numbers

Amogh Huilgol
  • 1,252
  • 3
  • 18
  • 25

2 Answers2

3

For non-consecutive numbers you needs a means of sorting them in O(n). In this case you can use BitSet.

int[] ints = {2, 4, 6, 7, 3, 1};
BitSet bs = new BitSet();
IntStream.of(ints).forEach(bs::set); 

// you can search for the longer consecutive sequence.
int last = 0, max = 0;
do {
    int set = bs.nextSetBit(last);
    int clear = bs.nextClearBit(set + 1);
    int len = clear - set;
    if (len > max)
        max = len;
    last = clear;
} while (last > 0);
System.out.println(max);
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

Traverse the array once and build the hash map whose key is a number from the input array and value is a boolean variable indicating whether the element has been processed or not (initially all are false). Traverse once more and do the following: when you check number a, put value true for that element in the hash map and immediately check the hash map for the existence of the elements a-1 and a+1. If found, denote their values in the hash map as true and proceed checking their neighbors, incrementing the length of the current contigous subsequence. Stop when there are no neighbors, and update longest length. Move forward in the array and continue checking unprocessed elements. It is not obvious at the first glance that this solution is O(n), but there are only two array traversals and hash map ensures that every element of the input is processed only once.

Main lesson - if you have to reduce time complexity, it is often neccesary to use additional space.

Miljen Mikic
  • 14,765
  • 8
  • 58
  • 66
  • Note: Java's `boolean[]` typically uses 1 byte per boolean. BitSet or similar would be more compact. – Peter Lawrey Feb 06 '16 at 18:07
  • i didn't do the math, but it's not O(N) – Jérémie B Feb 06 '16 at 18:23
  • @JérémieB Although it doesn't seem O(n) at the first glance, it is. You process each element from the input only once, hash map ensures that. When you stumble upon the processed element in the second traversal of the input array, just skip it. – Miljen Mikic Feb 06 '16 at 18:29
  • yes, but a hashmap is not free. it's O(1) at best, not on average/worst. – Jérémie B Feb 06 '16 at 18:32
  • @NiklasB Of course not. Hash code of an integer is the value of number itself, but the hash map implementation is still prone to collisions and rehashing, so yes, it is not O(1) always - that was incorrect. However, when evaluating the complexity of hash map operations, one usually assumes O(1), at interviews as well. – Miljen Mikic Feb 06 '16 at 19:24