Solution 1
- Given it is a rotated array, then the left first half values are greater than the right later half values.
-
Purpose: To find the
last position of the 1st half
and first position of 2nd half
- In order to do this, we need to keep
left pointer
always points to 1st half
, and right pointer
always points to 2nd half
- when
distance between left and right pointer == 1
, then we found the last position of the 1st half
and first position of 2nd half
; then the minimum one is the first position of the 2nd half
Solution 2
- 求出middle,用nums [middle]与nums[end]比较
if (nums [middle] < nums[end]) {
end = middle;
} else if (nums [middle] > nums[end]) {
start = middle;
}
- 当
start + 1 == end
时,跳出循环。return Math.min (nums [start], nums[end]);
Code1
// iterative solution
class Solution {
public int findMin(int[] nums) {
int left = 0;
int right = nums.length - 1;
// purpose: to find the last element of subarray1 and first element of subarray2
// In order to do this, we need to keep left pointer always points to subarray1, and right poitner --> subarray2
// when distance between left and right is 1, then we found the last of subarray 1 and first of subarray2
// minimum is the first element of subarray2
// this condition guarantee that it is rotated, if not then the first element is the mini
while (nums[left] > nums[right]) {
int middle = left + (right - left) / 2;
if (left + 1 == right) {
return nums[right];
}
if (nums[middle] > nums[left]) {
// middle is inside subarray1, so move left to middle
left = middle;
} else {
// middle is inside subarray2, then move right to middle
right = middle;
}
}
return nums[left];
}
}
// recursion solution
class Solution {
public int findMin(int[] nums) {
int left = 0;
int right = nums.length - 1;
return findMin (nums, left, right);
}
public int findMin (int[] nums, int left, int right) {
if (nums[left] < nums[right]) {
return nums[left];
}
if (left + 1 >= right) {
return Math.min (nums[left], nums[right]);
}
int middle = left + (right - left) / 2;
int min1 = findMin (nums, left, middle);
int min2 = findMin (nums, middle + 1, right);
return Math.min (min1, min2);
}
}
Code2
class Solution {
public int findMin(int[] nums) {
if (nums == null || nums.length == 0)
return 0;
int start = 0;
int end = nums.length - 1;
while (start + 1 < end) {
int middle = start + (end - start) / 2;
if (nums [middle] < nums[end]) {
end = middle;
} else if (nums [middle] > nums[end]) {
start = middle;
}
}
return Math.min (nums [start], nums[end]);
}
}