算法题解2_求连续子数组的最大和
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个排好序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1
解法
最直观的解法并不难,从头到尾遍历一次就行,但是这样就太low了。直观上应该用二分法 low,middle,high。如果 middle > low,说明middle仍然在前半部分,则令low = middle; 如果middle < high,说明middle在后部分,另high = middle
代码如下:
public static int min(int[] nums) {
if ( null == nums || 0 == nums.length )
return -1; // -1代表出错
int low = 0;
int high = nums.length - 1;
int middle = low;
while ( nums[low] >= nums[high] ) {
if ( 1 == high - low ) {
middle = high;
break;
}
middle = (low + high) / 2;
// 特殊情况
if( nums[low] == nums[middle] && nums[middle] == nums[high] )
return minInOrder(nums, low, high);
if ( nums[middle] >= nums[low] )
low = middle;
else if ( nums[middle] <= nums[high] )
high = middle;
}
return nums[middle];
}
private static int minOrder(int[] nums, int low, int high) {
int min = nums[low];
for (int i = low; i <= high; i++) {
if ( nums[i] < min)
min = nums[i];
}
return min;
}
public static void main(String[] args) {
int[] arr = {3, 4, 5, 1, 2};
System.out.println( min(arr) );
}
注意这里的一个特殊情况: {1,0,1,1,1}和{1,1,1,0,1}都是{0,1,1,1,1}的旋转,但是不久后发现low,high,middle全部相等,这时候只能蛮力求解
Written on January 6, 2016