【剑指offer】求旋转数组的最小数字8

#include<iostream>
#include <stdio.h>

//求旋转数组的最小数字
int MinInOrder(int * numbers,int index1,int index2)
{
	int result=numbers[index1];
	for(int i=index1+1; i<= index2; ++i)
	{
		if(result > numbers[i])
			result=numbers[i];
	}
	return result;
}
int Min(int * numbers,int length)
{
	if(numbers == NULL || length <= 0)
		throw new std::exception("Invalid parameters");
	int index1=0;
	int index2=length-1;
	//如果排序数组的前面的0个元素搬到后面,即排序数组本身仍然是一个旋转。那么数组的第一个数组
	//为最小的数组,可以直接返回,所以把indexMid设为index1
	int indexMid=index1;
	while(numbers[index1] >= numbers[index2])
	{
		// 如果index1和index2指向相邻的两个数,
        // 则index1指向第一个递增子数组的最后一个数字,
        // index2指向第二个子数组的第一个数字,也就是数组中的最小数字
		if(index2-index1==1)
		{
			indexMid=index2;
			break;
		}
		indexMid=(index1+index2)/2;

		// 如果下标为index1、index2和indexMid指向的三个数字相等,
        // 则只能顺序查找 此处不明白可查看书上内容
		if(numbers[index1]==numbers[index2] && numbers[index1] == numbers[indexMid])
			return MinInOrder(numbers,index1,index2);

		if(numbers[indexMid] >= numbers[index1])
			index1=indexMid;
		else if(numbers[indexMid] <= numbers[index2])
			index2=indexMid;
	}
	return numbers[indexMid];
}
// ====================测试代码====================
void Test(int* numbers, int length, int expected)
{
    int result = 0;
    try
    {
        result = Min(numbers, length);

        for(int i = 0; i < length; ++i)
            printf("%d ", numbers[i]);

        if(result == expected)
            printf("\tpassed\n");
        else
            printf("\tfailed\n");
    }
    catch (...)
    {
        if(numbers == NULL)
            printf("Test passed.\n");
        else
            printf("Test failed.\n");
    }
}

void main( )
{
    // 典型输入,单调升序的数组的一个旋转
    int array1[] = {3, 4, 5, 1, 2};
    Test(array1, sizeof(array1) / sizeof(int), 1);

    // 有重复数字,并且重复的数字刚好的最小的数字
    int array2[] = {3, 4, 5, 1, 1, 2};
    Test(array2, sizeof(array2) / sizeof(int), 1);

    // 有重复数字,但重复的数字不是第一个数字和最后一个数字
    int array3[] = {3, 4, 5, 1, 2, 2};
    Test(array3, sizeof(array3) / sizeof(int), 1);

    // 有重复的数字,并且重复的数字刚好是第一个数字和最后一个数字
    int array4[] = {1, 0, 1, 1, 1};
    Test(array4, sizeof(array4) / sizeof(int), 0);

    // 单调升序数组,旋转0个元素,也就是单调升序数组本身
    int array5[] = {1, 2, 3, 4, 5};
    Test(array5, sizeof(array5) / sizeof(int), 1);

    // 数组中只有一个数字
    int array6[] = {2};
    Test(array6, sizeof(array6) / sizeof(int), 2);

    // 输入NULL
    Test(NULL, 0, 0);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值