This is a general question, which could be applicable to any given language like C,C++,Java etc.
I figured any way you implement it, you can’t get more efficient than using 2 loops, which gives an efficiency of n^2.
for(i=0;i<n;i++)
for(j=0;j<n;j++)
a[i][j]=1;
I was asked this at an interview recently, and couldn’t think of anything more efficient. All I got from the interviewer was that I could use recursion or convert the 2D array to a linked list to make it more efficient than n^2. Anyone know if this is possible, and if yes, how? At least theoretically, if not practically.
edit: The actual question gives me the coordinates of two cells, and I have to fill the paths taken by all possible shortest routes with 1.
eg, if i have a 5×5 matrix, and my two coordinates are (2,0) and (3,3), I’d have to fill:
(2,0)(2,1)(2,2)(2,3)
(3,0)(3,1)(3,2)(3,3)
while leaving the rest of the cells as they were.
It depends on what you mean. If the question is about plain arrays, meaning a sequence of contiguos memory locations and for initialization you mean putting a value in every memory location of this “matrix” then the answer is no, better than O(n*m) is not possible and we can prove it:
Let us assume that algorithm
fill(A[n][m], init_val)is correct(i.e. fills all the memory locations ofA) has complexityg(n,m)which is less thanO(n*m)(meaningg(n,m)is not part ofΩ(n*m)), then for big enoughnandmwe will have thatg(n,m) < n*m= number of memory locations. Since filling a memory location requires one operation the algorithmfillcan fill at mostg(n,m)locations[actually half because it must also do at least an operation to “select” a different memory location, except if the hardware provides a combined operation] which is strictly less thann*m, which imply that the algorithmfillis not correct.The same applies if filling
kmemory locations takes constant time, you simply have to choose biggernandmvalues.As other already suggested you can use other data-structures to avoid the
O(n^2)initialization time. amit suggestion uses some kind of lazy-evaluation, which allows you to not initialize the array at all but do it only when you access the elements.Note that this removes the
Ω(n^2)cost at the beginning, but requires more complex operations to access the array’s elements and also requires more memory.It is not clear what your interviewer meant: converting an array into a linked-list requires
Ω(L)time(where L is the length of the array), so simply converting the whole matrix into a linked-list would requireΩ(n^2)time plus the real initialization. Using recursion does not help at all,you simply end up in recurrences such as
T(n) = 2T(n/2) + O(1)which would again result in no benefit for the asymptotic complexity.As a general rule all algorithms have to scan at least all of their input, except it they have some form of knowledge beforehand(e.g. elements are sorted). In your case the space to scan is
Θ(n^2)and thus every algorithm that wants to fill it must be at leastΩ(n^2). Anything with less than this complexity either make some assumption(e.g. the memory contains the initializer value by default ->O(1)), or solves a different problem(e.g. use lazy arrays, or other data structures).