Finding an element in partially sorted array
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
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);
}
}
}
}
精彩评论