代码题--C++--旋转数组求最小值

博客围绕C++旋转数组求最小值的代码题展开。先给出题目,即输入排好序数组的旋转,输出最小元素。接着介绍解题思路,使用二分查找逼近最小值,分三种情况讨论。最后给出完整C++代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码题--C++--旋转数组求最小值


题目描述:

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个排好序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。

输入描述:
一个排好序的数组的一个旋转
数组长度不超过1000000
输出描述:
该数组的最小值
示例1
输入
3 4 5 1 2
输出
1

解题思路:

使用二分查找的方法,逐步的逼近这个最小值,首先这个旋转数组将一个非递减的数组分成了两个子数组,前一个数组的值都比后一个数组的值大,并且两个子数组都是非递减的数组,而且我们可以知道这个最小值肯定是在前一个数组和后一个数组的交界出。也就是后一个数组的第一个值。

采用二分法解答这个问题,mid  =  low + (high - low)/2;

需要考虑三种情况:

(1)array[mid] > array[high]

出现这种情况array类似[3, 4, 5, 0, 1],此时最小数字移动在mid的右边。low = mid + 1;

(2)array[mid] == array[high]

出现这种情况array类似[0, 1, 1, 1, 1,]或者[1, 1, 1, 0, 1],此时最小数字不好判断在mid左边还是右边,只好一个个的试。high = high - 1;

(3)array[mid] < array[high]
出现这种情况的array类似[2,3,4,5,6],此时最小数字一定就是array[mid]或者在mid的左边。因为右边必然都是递增的。 high = mid;
        注意:如果待查询的范围最后只剩两个数,那么mid 一定会指向下标靠前的数字
        比如 array = [4,6]
        array[low] = 4 ;array[mid] = 4 ; array[high] = 6 ;
        如果high = mid - 1,就会产生错误, 因此high = mid
        但情形(1)中low = mid + 1就不会错误

完整C++代码如下:

#include <iostream>
using namespace std;
#include <vector>
int Xuanzhuan_min(vector<int> vec)
{
	int res = 0;
	int low = 0;
	int size = vec.size();
	int high = size - 1;
     if(size==0)
            return 0;
	//1.vec[mid] == vec[high]; high = high -1;
	//2.vec[mid] >= vec[high] ;low = mid +1;
	//3.vec[mid] <= vec[high] ;high = mid;
	
	while (low < high)
	{
		int mid = low + (high - low) / 2;
		if (vec[mid] > vec[high])
		{
			low = mid + 1;
		}
		else if (vec[mid] == vec[high])
		{
			high = high - 1;
		}
		else
		{
			high = mid;
		}
	}
	res = vec[low];
	return res;
}
int main()
{
    vector<int> vec ;
    char ch;//由于数组长度不确定,采用字符读取,然后再转为数字,压入vector中。
    int num = 0;
    while((ch = getchar()) != '\n'){
        if(ch != ' '){
            num = 10 * num + (ch - '0');
        } else {
            vec.push_back(num);
            num = 0;
        }
    }
    vec.push_back(num);
    int res = Xuanzhuan_min(vec);
    cout << res;
    
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值