[leetcode] 153.Find Minimum in Rotated Sorted Array

来源:互联网 发布:linux中的cut命令 编辑:程序博客网 时间:2024/06/06 20:14

题目:
Suppose a sorted array is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

You may assume no duplicate exists in the array.
题意:
一个有序数组在某个位置翻转了,现在需要找出最小值,数组中每个元素都不一样。
思路:

  1. 观察可得,最小的那个元素比它之前的元素要小。如果当前找到的元素比最后的元素小,说明当前元素处在后面的有序部分,那么下次搜索的范围应该是当前元素的前一个位置到start位置。如果当前元素比后面元素大,说明处在前面的有序部分,那么下一次的二分区域就变成从当前元素的下一个位置到end位置。
    代码如下:
class Solution {public:    int findMin(vector<int>& nums)     {        int size = nums.size();        if(nums.size() == 0)return 0;        int small = 0, big = size - 1, middle = (small + big + 1) / 2;        while(small <= big)        {            if(middle == 0 || nums[middle] < nums[middle - 1])return nums[middle];            if(nums[middle] > nums[size - 1])            {                small = middle + 1;            }            else big = middle - 1;            middle = (big + small + 1) / 2;        }    }};

2.我们换个思路,用两个指针,p1指向前面那部分有序数组,p2指向后面那部分有序数组,如果p1 + 1 = p2,说明p2是后面有序数组的第一个元素,也就是我们要找的最小元素,那么就返回这个元素。初始化时让p1指向数组的第一个元素,让p2指向数组的最后一个元素。middle用来标记p1与p2的中间元素。如果旋转位置是数组的末尾,那么本质就是代表数组没有旋转,需要考虑这种特殊情况。
其余情况比较middle指向的元素是在前面的那个数组里面还是在后面的数组里面。如果middle在前面的数组里面,那么将p1设为middle,否则将怕p2缩小为middle,来缩小二分查找的范围。
代码如下:
class Solution {
public:
int findMin(vector& nums) {
if (nums.size() == 0)return -1;
return findMin(nums, 0, nums.size() - 1);
}
int findMin(vector& nums, int begin, int end) {
if (begin == end)return nums[begin];
int middle = begin;//之所以让middle初始化为begin,是有可能数组未经旋转,所以第一个元素就应该是最小值,如果数组未经旋转,那么nums[begin]此时一定是小于nums[end],所以下面的循环会跳过。
while (nums[begin] > nums[end]) {
if (begin == end - 1) {
middle = end;
break;
}
middle = begin + (end - begin) / 2;
if (nums[middle] >= nums[begin]) {
begin = middle;
}
else {
end = middle;
}
}
return nums[middle];
}
};

0 0
原创粉丝点击