This is an interview question. A sorted rotated array is a sorted array which was rotated 0 or more times.
For example: [1,2,3] -> [2,3,1]
Please tell me what do you think about the following (correctness, efficiency, coding conventions) and specifically if I can remove in some way the special handle for array of two elements:
static int findMax(int arr[]) {
return findMax(arr, 0 , arr.length - 1);
}
static int findMax(int arr[], int low, int high) {
int middle;
if (low == high) {
return arr[low];
}
if ( Math.abs(high - low) == 1 ) {
return Math.max(arr[low], arr[high]);
}
middle = (low + high) >> 1;
if (arr[middle] > arr[middle + 1]) {
return arr[middle];
}
if (arr[low] > arr[middle]) {
return findMax(arr, low, middle - 1);
}
return findMax(arr, middle + 1, high);
}
-
\$\begingroup\$ Welcome to Code Review! Have you tested this? How? Does it pass your tests? What made you write this? Please add more context. More context => better questions => better answers. \$\endgroup\$Mast– Mast ♦2018年10月29日 11:22:14 +00:00Commented Oct 29, 2018 at 11:22
-
\$\begingroup\$ Yes, I wrote some nine tests which passed (different array cases). I wrote that because it's an interview question I saw in some site (preparation for an interview). \$\endgroup\$Rodrigo– Rodrigo2018年10月29日 17:18:03 +00:00Commented Oct 29, 2018 at 17:18
-
\$\begingroup\$ Somebody defaced your question and you accepted it. Please don't. The additional context was helpful and shouln't have been removed. \$\endgroup\$Mast– Mast ♦2018年10月29日 17:24:41 +00:00Commented Oct 29, 2018 at 17:24
1 Answer 1
Math.abs
inMath.abs(high - low) == 1
is suspicious.high
should always be not less thanlow
. Remove it.middle = (low + high) >> 1
may (and will) overflow. Domiddle = low + (high - low) >> 1
.That said,
>> 1
is no better than)/ 2
.Java is notorious in not eliminating the tail recursion. You should do it manually. First, rewrite it in a tail-recursive form:
if (low == high) { return arr[low]; } if ( Math.abs(high - low) == 1 ) { return Math.max(arr[low], arr[high]); } middle = (low + high) >> 1; if (arr[middle] > arr[middle + 1]) { return arr[middle]; } if (arr[low] > arr[middle]) { high = middle - 1; } else { low = middle + 1; } return findMax(arr, low, high);
then eliminate a recursive call:
while (high - low > 2) { middle = low + (high - low) / 2; if (arr[middle] > arr[middle + 1]) { return arr[middle]; } if (arr[low] > arr[middle]) { high = middle - 1; } else { low = middle + 1; } } return Math.max(arr[low], arr[high]);
-
\$\begingroup\$ This should have
while (high - low >= 2) {
. Consider a three element array. Solow
is 0 andhigh
is 2; your code wouldreturn Math.max(arr[0], arr[2]);
without ever entering the body of the loop. And frankly, I think that's overcomplicating things. The code works fine withwhile (high > low) {
andreturn arr[low];
. No 2 orMath.max
needed. \$\endgroup\$mdfst13– mdfst132022年07月30日 23:25:57 +00:00Commented Jul 30, 2022 at 23:25
Explore related questions
See similar questions with these tags.