Find Minimum in Rotated Sorted Array II

题目大意: 寻找递增的旋转数组里面最小的数

解题思路:折半查找。

有序的旋转数组前半部分和后半部分都是递增的序列。数组第一个元素要大于等于最后一个元素。否则数组本身就是个递增的序列,第一个元素就是最小数

如果不是递增序列,则取中间数。

1.如果中间数大于数组的第一个元素,说明最小数存在后半段,范围缩小到中间数到最后一个元素左开右闭区间

2.如果中间数小于数组的第一个元素,说明最小数存在前半段,范围缩小到第一个元素和中间数闭区间左开右闭区间。

3.如果中间数等于数组第一个元素,需要特殊处理。

 3.1 如果中间数大于数组最后一个元素,说明最小数存在后半段, 范围缩小到中间数到最后一个元素左开右闭区间

 3.2 如果中间数等于数组最后一个元素,则需分别找出这第一个元素到中间数,和中间数到最后一个元素这两个区间的最小数,然后对这两个最小数进行比较,最后取最小值。


可以用递归实现:

#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;

class Solution {
	public:
		int findMin(vector<int> &num) {
			return assistFindMin(num, 0, num.size() - 1);
		}
		
private:
		int assistFindMin(vector<int> &num, int begin, int end) {
			if(begin == end || num[begin] < num[end])
			  return num[begin];
			int mid = (begin + end) >> 1;
			if(num[mid] > num[begin])
			  return assistFindMin(num, mid + 1, end);
			else if(num[mid] < num[begin])
			  return assistFindMin(num, begin + 1, mid);
			else {
				if(num[mid] > num[end])
				  return assistFindMin(num, mid + 1, end);
				else 
				  return min(assistFindMin(num, begin, mid), assistFindMin(num, mid + 1, end));
			}
		}

		int min(int a, int b) {
			return a <= b ? a : b;
		}
};

int main() {
	Solution solution;
	int array1[5] = {1, 2, 3, 4, 5};
	int array2[5] = {2, 2, 2, 2, 2};
	int array3[7] = {4, 5, 6, 7, 0, 1, 2};
	int array4[5] = {1, 0, 1, 1, 1};
	vector<int> num1(array1, array1 + sizeof(array1) / sizeof(array1[0]));
	vector<int> num2(array2, array2 + sizeof(array2) / sizeof(array2[0]));
	vector<int> num3(array3, array3 + sizeof(array3) / sizeof(array3[0]));
	vector<int> num4(array4, array4 + sizeof(array4) / sizeof(array4[0]));;
	printf("test 1: %d\n", solution.findMin(num1));
	printf("test 2: %d\n", solution.findMin(num2));
	printf("test 3: %d\n", solution.findMin(num3));
	printf("test 4: %d\n", solution.findMin(num4));
	return 0;
}


非递归的话,3.2步需要顺序比较:

#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;

class Solution {
	public:
		int findMin(vector<int> &num) {
			int begin = 0;
			int end = num.size() - 1;
			int mid = begin;
			while(begin <= end && num[begin] >= num[end]) {
				if(begin == end)
				  return num[begin];
				mid = (begin + end) >> 1;
				if(num[mid] > num[begin])
				  begin = mid + 1;
				else if(num[mid] < num[begin]) {
					begin++;
					end = mid;
				} else {
					if(num[mid] > num[end]) 
					  begin = mid + 1;
					else {
						int minVal = num[begin];
						for(int i = begin + 1; i <= end; i++) {
							if(minVal > num[i])
							  minVal = num[i];
						}
						return minVal;
					}
				}
				if(num[begin] < num[end])
				  return num[begin];
			}
			return num[mid];
		}
		
};

int main() {
	Solution solution;
	int array1[5] = {1, 2, 3, 4, 5};
	int array2[5] = {2, 2, 2, 2, 2};
	int array3[7] = {4, 5, 6, 7, 0, 1, 2};
	int array4[5] = {1, 0, 1, 1, 1};
	vector<int> num1(array1, array1 + sizeof(array1) / sizeof(array1[0]));
	vector<int> num2(array2, array2 + sizeof(array2) / sizeof(array2[0]));
	vector<int> num3(array3, array3 + sizeof(array3) / sizeof(array3[0]));
	vector<int> num4(array4, array4 + sizeof(array4) / sizeof(array4[0]));;
	printf("test 1: %d\n", solution.findMin(num1));
	printf("test 2: %d\n", solution.findMin(num2));
	printf("test 3: %d\n", solution.findMin(num3));
	printf("test 4: %d\n", solution.findMin(num4));
	return 0;
}


评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值