【剑指offer】——二分查找相关例题总结

一、旋转数组的最小值

1、 题目要求

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

2、题目分析

首先,我们可以明确的是该旋转数组的规律
旋转之后的数组实际上可以划分为两个排序的子数组,而且前面子数组的元素都大于或者等于后面子数组的元素
这样,我们就可以依照这个规律来探索问题的答案了。我们还是以简单通俗易懂的方式,以具体的列子来分析。

情况一:
以数组{3,4,5,1,2}为列子。首先定义两个指针,分别指向数组的第一个元素和最后一个元素。有阴影的部分就是第二个子数组
在这里插入图片描述
计算此时的中间元素下标=(0+4)/2=2。下标为2的数组元素值为5.由于5>p1所指向的数字3,所以中间的数值在第一个子数组中。把p1指向中间的数字。
在这里插入图片描述
此时p1,p2中间的数字1小于p2指向的数字。中间的数字在第二个子数组中。把p2指向中间的数字。
在这里插入图片描述
此时,p1和p2指向两个相邻的数字,则
p2
指向的是数组中的最小数字。
为什么p2为最小数字?
因为当两个指针相距只有一个位置的时候表明p1已经指向了第一个递增数组的最后一个元素,p2指向了第二个递增数组的第一个元素。所以p2指向的即为数组中的最小元素。

情况二:
当遇到p1,p2和中间的指针指向的数字都相同的情况下时,如数组{0,1,1,1,1}。{1,0,1,1,1}和{1,1,1,0,1}都为该递增数组的旋转
在这里插入图片描述
如上图所示,这种情况就不明白中间元素到底是属于哪一个递增数组的,所以就不得不采取顺序查找的方式进行。

情况三:
如果把排序的数组的前面0个元素搬到最后面,即数组本身,这仍然是数组的一个旋转。
这种情况就直接返回p1说指向的元素即可。这也是把indexMid赋值给p1的原因。

3、代码实现

int MinInOrder(int* numbers, int p1, int p2)
{
   
    int result = numbers[p1];
    for (int i = p1 + 1; i <= p2; i++)
    {
   
        if (result > numbers[i])
            result = numbers[i];
    }
    return result;
}
int Min(int* numbers, int length)
{
   
	if (numbers == nullptr || length <= 0)
		throw new::std::exception("Invalid parameters");

	int p1 = 0;
	int p2 = length - 1;
	int indexmid = p1;
	while (numbers[p1] >= numbers[p2
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值