I had a following interview question.
There is an array of nxn elements. The array is partially sorted i.e the biggest element in row i
is smaller than the smallest element in row i+1
.
How can you find a given element with complexity O(n)
Here is my take on this:
You should go to the row n/2.And start compare for example you search for 100 and the first number you see is 110 so you know it's either in this row or in rows above now you go n/4 and so on.
From the comments
Isn't it O(n * log n) in total? He has to parse through every row that he reaches per binary search, therefore the number of linear searches is multiplied with the number of rows he will have to scan in average. – Martin Matysiak 5 mins ago.
I am not sure that is a right solution. Does anyone have something better
In computer science, partial sorting is a relaxed variant of the sorting problem. Total sorting is the problem of returning a list of items such that its elements all appear in order, while partial sorting is returning a list of the k smallest (or k largest) elements in order.
Many sorting algorithms are available, but the one which is best suited for the almost sorted array is the insertion sort.
Algorithm to find pivot element of a rotated array. Find the middle index as (leftIndex + rightIndex)/2. Let middle index be mid. Check if inputArray[mid] is a pivot element. If (inputArray[mid-1] > inputArray[mid] < inputArray[mid+1]) is true then inputArray[mid] is pivot element.
Your solution indeed takes O(n log n)
assuming you're searching each row you parse. If you don't search each row, then you can't accurately perform the binary step.
O(n)
solution:
Pick the n/2
row, instead of searching the entire row, we simply take the first element of the previous row, and the first element of the next row. O(1)
.
We know that all elements of the n/2
row must be between these selected values (this is the key observation). If our target value lies in the interval, then search all three rows (3*O(n) = O(n)
).
If our value is outside this range, then continue in the binary search manner by selecting n/4
if our value was less than the range, and 3n/4
row if the value was greater, and again comparing against one element of adjacent rows.
Finding the right block of 3 rows will cost O(1) * O(log n)
, and finding the element will cost O(n)
.
In total O(log n) + O(n) = O(n)
.
Here is a simple implementation - since we need O(n) for finding an element within a row anyhow, I left out the bin-search...
void search(int n[][], int el) {
int minrow = 0, maxrow;
while (minrow < n.length && el >= n[minrow][0])
++minrow;
minrow = Math.max(0, minrow - 1);
maxrow = Math.min(n.length - 1, minrow + 1);
for (int row = minrow; row <= maxrow; ++row) {
for (int col = 0; col < n[row].length; ++col) {
if (n[row][col] == el) {
System.out.printf("found at %d,%d\n", row, col);
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With