有序数组旋转的问题
来源:互联网 发布:软件培训会议纪要 编辑:程序博客网 时间:2024/06/04 19:08
1、有序数组旋转后寻找数组中的最小值
一般情况下我们的第一反应肯定是遍历此数组,但这肯定不是我们所期望的,因为此数组是有序数组旋转而成,所以我们此时应该想到用二分法来寻找数组中的最小值。假设我们给定递增数组{0,1,2,3,4,5,6,7,8,9}
旋转后的数组有下面几种形式
{6,7,8,9,0,1,2,3,4,5}
{9,0,1,2,3,4,5,6,7,8}
{0,1,2,3,4,5,6,7,8,9}
{5,6,7,8,9,0,1,2,3,4}
通过观察可以发现,在经过旋转后的数组在寻找最小值的过程中0的前面的数总是大于0后面的数,所以我们可以以此为条件,在将范围缩小为2个数时,后面的数就是最小值,根据此思路代码如下:
<span style="font-family:Microsoft YaHei;font-size:14px;">int MinArray(int* a, int n){assert(a != NULL || n <= 0);int start = 0;int end = n - 1;int mid = start;while (a[start] >= a[end]) //确定数组经过旋转已经不是有序数组{if (end - start == 1) //当只剩两个数时直接返回较小值的下标{mid = end;break;}mid = (start + end) / 2;//如果a[start],a[mid],a[end]相等时,只能遍历寻找最小值if (a[mid] == a[start] && a[mid] == a[end]){int min = a[start];while (start <= end){if (a[start] < min){mid = a[start];}++start;}return min;}if (a[mid] >= a[start]){start = mid;}else if (a[mid] <= a[end]){end = mid;}}return a[mid];}</span>
上面的程序已经将一种特殊情况给处理了,例如下面这种例子
{1,0,1,1,1}
{1,1,1,0,1}
此时若直接进行比较,将会出现将最小值跳过的情况,所以我们在此种情况下只能采取遍历寻找最小值。
我们也可以使用下标的方式来实现寻找最小值,思路和上面的程序一样,代码如下:
上面是求去旋转有序数组的最小值,求最大值的思路和最小值的一样,只需要在循环结束返回时返回那个较大值即可。
<span style="font-family:Microsoft YaHei;font-size:14px;">int MinArray2(int* a, int n){assert(a != NULL || n <= 0);int start = 0;int end = n - 1;while (start < (start+end)/2) {int mid = (start + end) / 2;//如果a[start],a[mid],a[end]相等时,只能遍历寻找最小值if (a[mid] == a[start] && a[mid] == a[end]){int min = a[start];while (start <= end){if (a[start] < min){mid = a[start];}++start;}return min;}if (a[mid] >= a[start] && a[mid] <= a[end]) //此时数组有序,直接返回数组下标0{return 0;}if (a[mid] >= a[start]){start = mid;}else if (a[mid] <= a[end]){end = mid;}}if (a[start] > a[end]){return a[end];}return a[start];}</span>
上面是求去旋转有序数组的最小值,求最大值的思路和最小值的一样,只需要在循环结束返回时返回那个较大值即可。
2、有序数组旋转后给定数值返回此数值在数组中的下标
实现在一个旋转有序数组中寻找一个数并返回下标,很多人的第一反应肯定是直接遍历,但这样的话有序数组旋转的特性没有得到应用,所以我们需要分析旋转有序数组的特点,例如下面旋转有序数组
{5,6,7,8,9,0,1,2,3,4}
{6,7,8,9,0,1,2,3,4,5}
{0,1,2,3,4,5,,6,7,8,9}
通过观察上面的数组我们可以发现无论数组如何旋转,数组分成两个子数组时,一个肯定是有序的,所以我们可以利用此特性来实现寻找一个特定的数,每次将给定数值通过和有序数组的首尾两个值对比,来判断此数是否存在在这个数组中,如果在的话,将此数组递归,若不在,将另一个数组递归,重复此过程,直至首尾元素下标相同,或寻找到此给定数值。
依据上面的思路实现的代码如下:
<span style="font-family:Microsoft YaHei;font-size:14px;">int Search(int* a, int n, int x){assert(a != NULL || x <= 0);int start = 0;int end = n - 1;while (start < end){int mid = (start + end) / 2;if (a[mid] == x){return mid;}else if (a[mid] > a[start]){if (x <= a[mid] && x >= a[start]){end = mid;}else{start = mid;}}else if (a[end] > a[mid]){if (x >= a[mid] && x <= a[end]){start = mid;}else{end = mid;}}else{++start; //处理数组中有重复的数字}}return -1;}</span>
0 0
- 有序数组旋转的问题
- 有序数组或者有序数组的旋转数组 查找最小值
- 有序数组的旋转数组的最小值
- 旋转有序数组的二分查找
- 旋转有序数组的二分查找
- 旋转有序数组的二分查找
- 寻找旋转有序数组的最小值
- 求出有序数组旋转后的最小值
- 循环有序数组/旋转数组的二分查找
- 循环有序数组(旋转数组)的最小值
- 有序数组的组合问题
- 有序数组问题的思考
- C++求有序数组旋转之后的最小数字
- [LeetCode]33 旋转后的有序数组中的搜索
- [LeetCode]153 有序数组旋转后的最小值
- [LeetCode]154 有序数组旋转后的最小值 II
- 有序数组旋转后的元素值查找
- 在一个有序的旋转数组中,查找给定值
- 《将博客搬至CSDN》
- linux下ftp连接:530 Permission denied
- git零基础深入浅出 之 [git初探]
- Android APP编程单元测试实例详解(附源码)
- 排序__js
- 有序数组旋转的问题
- Linux启动/停止/重启Mysql数据库的方法
- mysql查询替换语句
- 使用Espresso Test Recorder编写Android测试
- 生活感悟-2016.06.14
- 抓取淘宝商品价格人气-http://hws.m.taobao.com/cache/wdetail/5.0
- 为什么大家都说大三是一个分水岭
- CocoaPods问题: CocoaPods was not able to update the `master` repo.if it is a unexpected issue and
- 【Java变成思想】笔记(一)