The correct solution to O (n) is quite complex and requires a significant amount of text, code and skills to explain and prove. More precisely, it does 3 pages to make it convincing, as can be seen in more detail here http://www.cse.yorku.ca/~andy/pubs/X+Y.pdf (found by simonzack in the comments).
This is basically a smart separation and rest algorithm, which, among other things, uses the fact that in a sorted n-on-n-matrix you can find in O(n) number of smaller elements / more than a given number k . It recursively breaks the matrix into smaller submatrices (taking only odd rows and columns, which leads to a submatrix having n/2 colums and n/2 rows), which, combined with the above step, leads to complexity O(n) + O(n/2) + O(n/4)... = O(2*n) = O(n) , This is crazy!
I cannot explain it better than paper , so I will explain the simpler solution O(n logn) :) .
O (n * logn):
This is an interview! You cannot get this O(n) solution on time. So, why not provide a solution that, although not optimal, shows what you can do better than the other obvious O(n²) candidates?
I will use the O(n) algorithm described above to find the number of numbers that are less than / greater than a given number k in the sorted n-by-n matrix. Keep in mind that we do not need a real matrix! The Cartesian sum of two arrays of size n , as described by OP, leads to a sorted matrix n-by-n , which we can model by considering the elements of the array as follows:
a[3] = {1, 5, 9}; b[3] = {4, 6, 8};
Thus, each row contains non-decreasing numbers, as well as each column. Now pretend you're assigned the number k . We want to find in O(n) how many numbers in this matrix are less than k , and how many are more. Clearly, if both values are less than (n²+1)/2 , this means that k is our median!
The algorithm is pretty simple:
int smaller_than_k(int k){ int x = 0, j = n-1; for(int i = 0; i < n; ++i){ while(j >= 0 && k <= a[i]+b[j]){ --j; } x += j+1; } return x; }
This basically counts how many elements match the condition in each row. Since the rows and columns are already sorted as shown above, this will give the correct result. And since both i and j repeat no more than n times each, the O(n) algorithm [Note that j does not get reset in the for loop]. The greater_than_k algorithm greater_than_k similar.
Now, how do we choose k ? This is part of logn . Binary Search! As mentioned in other answers / comments, the median should be the value contained in this array:
candidates[n] = {a[0]+b[n-1], a[1]+b[n-2],... a[n-1]+b[0]}; .
Just sort this array [also O(n*logn) ] and run a binary search on it. Since the array is now in non-decreasing order, he directly noticed that the number of numbers smaller than each candidate[i] is also a non-decreasing value (monotone function), which makes it suitable for binary search. The largest number k = candidate[i] , the result of which smaller_than_k(k) returns less than (n²+1)/2 , is the answer and obtained in log(n) iterations:
int b_search(){ int lo = 0, hi = n, mid, n2 = (n²+1)/2; while(hi-lo > 1){ mid = (hi+lo)/2; if(smaller_than_k(candidate[mid]) < n2) lo = mid; else hi = mid; } return candidate[lo];