寻找旋转排序数组中的最小值

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

请找出其中最小的元素

你可以假设数组中不存在重复元素

示例 1:

输入: [3,4,5,1,2]
输出: 1

示例 2:

输入: [4,5,6,7,0,1,2]
输出: 0
题目分析:

数组是升序排列的,且其中没有重复元素,只是有可能会在某个点上旋转,要求数组中的最小值。

涉及到排序的数组查找值,首先想到二分查找。

  1. 如果这个旋转数组只有一个数直接返回这个数;
  2. 如果这个旋转数组的第一个数小于数组的最后一个数,那么说明旋转数组本身就是升序的,也就是说没有进行旋转,直接返回第一数;
  3. 而对于其他情况,采取二分查找的思想进行查找,当在二分的过程中,找到这样的一个数(这个数既比它的左边的数下,又比它右边的数小),那么就是最小的数直接返回即可;
  4. 如果在循环结束以后没有找到,说明肯定是在边界,因为最小值如果在中间,那么必然已经经过了判断直接返回了结果,所以这个时候只需要比较数组的第一个数和最后一个数。
代码实现:
public int findMin(int[] nums)
{
   if (nums.length == 1)
       return nums[0];
   if (nums[0] < nums[nums.length - 1])
       return nums[0];

   int left = 0;
   int right = nums.length - 1;

   while (left <= right)
   {
       int mid = left + (right - left) / 2;
       if ((mid + 1) < nums.length && nums[mid] < nums[mid + 1] && nums[mid] < nums[mid - 1])
           return nums[mid];
       else if (left >= 1 && (left + 1) < nums.length && nums[left] < nums[left - 1] && nums[left] < nums[left + 1])
           return nums[left];
       else if (right >= 1 && (right + 1) < nums.length && nums[right] < nums[right - 1] && nums[right] < nums[right + 1])
           return nums[right];
       else if (nums[mid] > nums[0])
           left = mid + 1;
       else
           right = mid - 1;
   }

   return nums[0] < nums[nums.length - 1] ? nums[0] : nums[nums.length - 1];
}
主函数:
public static void main(String[] args)
{
   S3 s = new S3();
   int[] res1 = new int[]{3,4,5,1,2};
   int[] res2 = new int[]{4,5,6,7,0,1,2};
   int[] res3 = new int[]{2,1};
   System.out.println(s.findMin(res1));
   System.out.println(s.findMin(res2));
   System.out.println(s.findMin(res3));
}
运行结果:

1
0
1

你可能感兴趣的:(数据结构,数据结构与算法2018,旋转数组,排序数组,最小值,二分查找,LeetCode)