GeeksforGeeks » Interview Questions
Google Interview Question for Software Engineer/Developer about Data Structure
(11 posts)-
Design a data structure that can be used instead of an array and avoids the "high-cost" (i.e. O(n)) of initializing the array. the data structure ought to holds n items and supports the following operations in O(1) time:
* Init – Initializes the data structure to empty.
* Set(i, x) – Sets item x at index i in the data structure.
* Get(i) – Gets the item stored in index i (or 'empty' if nothing is there).
Remark: the data structure should use O(n) space. -
Standard vector implementation can serve the purpose. Amortized complexity is constant.
-
@venki can you explain where r u using O(n) space & how u are init in O(1) ??
-
Use three un-initialized array, instead of one. The first array will
contain the actual elements of array, while the other two will
be used to ensure the validity of an entry.A[1..n] --- contains actual elements of array
B [1..n] --- contains pointer to the third array
C [1..n] --- contains pointer to the second array
size -- number of valid entries in AInvariant: For each index i, if A[i] has been assigned then
B[i] < size, and C[B[i]] = i;Init: size = 0; Set(i, x): p = B[i]; if (p >= size || C[p] != i) // a new entry { C[size] = i; B[i] = size; size++; } A[i] = x; Get (i) : p = B[i]; if ( p >= size || C[p] != i) // unassigned index generate some error; else return A[i]; -
@abc i didnt understand the need of three arrays this pointer indirection from one array to other i am not able to fathom.
and in your intialize function setting size to 0 does this suffice as initialising?
ill expect something as
a[]={0}; -
'
Get (i) :
p = B[i];
if ( p >= size || C[p] != i) // unassigned index
generate some error;
else
return A[i];
'If the array is initialized to value y, then in this part instead of
generating error, one should return y.The two arrays B and C are only to ensure, whether a location
has been assigned a value other than y (which was assigned
during initialization). Since, we cannot initialize the array due
to complexity constraints, this is one way to ensure whether
a particular index contains user assigned value or garbage. -
@abc makes sense :)
-
@abc on second thought cant we do it with only 1 array and one bit vector. Bit vector will help us track whether value in array is initialized or garbage
for ex
A[i] is the array and b is the bit vector having number of bits equal to number of element in array when we initialise ith elemnt in array we set corresponding bit to 1 in bit vector.... size is ofcourse there for initialising the data structure to empty..
what say? -
To rajcools:
But then again you have the problem that you cannot initialize the
bit-vector due to complexity constraints. That means you cannot
be sure whether an entry in the vector is genuine, or garbage. -
Can't we just take one extra array b[i] and check if ' b[i] = i ' , to check if ith block is set or not?
-
Denote the huge array by T . We also have a
stack implemented by an array S. The size of S equals the number of keys actually
stored, so that S should be allocated at the dictionarys maximum size. The stack
has an attribute top[S], so that only entries S[1 . . top[S]] are valid.
The idea of this scheme is that entries of T and S validate each other. If key k is
actually stored in T , then T [k] contains the index, say j , of a valid entry in S, and
S[ j ] contains the value k. Let us call this situation, in which 1 ≤ T [k] ≤ top[S],
S[T [k]] = k, and T [S[ j ]] = j, a validating cycle.
Assuming that we also need to store pointers to objects in our direct-address table,
we can store them in an array that is parallel to either T or S. Since S is smaller
than T , well use an array S, allocated to be the same size as S, for these pointers.
Thus, if the Array contains an object x with key k, then there is a validating
cycle and S[T [k]] points to x.
The operations work as follows:
• Initialization: Simply set top[S] = 0, so that there are no valid entries in the
stack.
• SEARCH: Given key k, we check whether we have a validating cycle, i.e.,
whether 1 ≤ T [k] ≤ top[S] and S[T [k]] = k. If so, we return S[T [k]],
and otherwise we return NIL.
• INSERT: To insert object x with key k, assuming that this object is not already
in the dictionary, we increment top[S], set S[top[S]] ← k, set S[top[S]] ← x,
and set T [k] ← top[S].
• DELETE: To delete object x with key k, assuming that this object is in the
dictionary, we need to break the validating cycle. The trick is to also ensure
that we dont leave a hole in the stack, and we solve this problem by moving
the top entry of the stack into the position that we are vacatingand then Þxing
up that entrys validating cycle.S[T [k]] ← S[top[S]]
S[T [k]] ← S[top[S]]
T [S[T [k]]] ← T [k]
T [k] ← 0
top[S] ← top[S] − 1(This a master-piece by CLRS)
Reply
You must log in to post.