题目:

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。

输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。

例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。

思路:

1、遍历数组,找到数组的最小值,时间复杂度O(n);

2、二分查找,时间复杂度O(logn)

注意旋转数组的循环不变量,A[left]>=A[right](这道题的数组为非递减数组,并非严格的递增数组)

特例:无旋转情况以及{0,1,1,1,1,1}旋转数组

查找过程:

旋转数组可以看成两个递增(非减)数组,通过前后两个指针left,right分别指向数组的首尾,

当满足循环不变量时A[left]>=A[right],mid=(left+right)/2,

如果A[mid]>=A[left],说明最小值存在mid后面部分,left=mid;

如果A[mid]<=A[left],说明最小值存在mid前面部分,right=mid;

经过循环之后,最终left会指向第一个递增数组的最后一个数,right会指向第二个递增数组的第一个数,即最小值mid=right。

最终return A[mid];

解决特例问题:

  • 无旋转数组:数组就是递增的,返回第一个数,即A[left],因此mid=left即可;
  • {0,1,1,1,1,1}类似旋转数组:不满足上述查找过程,只能遍历数组。

代码:

#include <iostream>
#include <vector> using namespace std; int MinInOrder(int* arr,int left,int right){
int result=arr[left];
for(int i=left+1;i<=right;i++){
if(result>arr[i])
result=arr[i];
}
return result;
} int Min(int* numbers,int length){
if(numbers==NULL || length<=0)
return -1;
int left=0;
int right=length-1;
int mid=left;
while(numbers[left]>=numbers[right]){
if(right-left==1){
mid=right;
break;
}
mid=left+((right-left)>>1);
if(numbers[left]==numbers[right] && numbers[left]==numbers[mid])
return MinInOrder(numbers,left,right);
if(numbers[mid]>=numbers[left])
left=mid;
else
right=mid;
}
return numbers[mid];
} int main()
{
int A[]={1,0,1,1,1,1,1,1};
int len=sizeof(A)/sizeof(A[0]);
Solution s;
vector<int> nums(A,A+len);
cout<<s.minNumberInRotateArray(nums)<<endl;
cout<<Min(A,len)<<endl;
return 0;
}

在线测试OJ:

http://www.nowcoder.com/books/coding-interviews/9f3231a991af4f55b95579b44b7a01ba?rp=1

AC代码:

class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
int len=rotateArray.size();
if(len==0)
return 0;
int left=0;
int right=len-1;
int mid=left;
//if(rotateArray[left]<rotateArray[right]);
// return rotateArray[left];
while(rotateArray[left]>=rotateArray[right]){
if(right-left==1){
mid=right;
break;
}
mid=left+((right-left)>>1);
if(rotateArray[left]==rotateArray[right] && rotateArray[left]==rotateArray[mid])
return MinInOrder(rotateArray,left,right);
if(rotateArray[mid]>=rotateArray[left])
left=mid;
else
right=mid;
}
return rotateArray[mid];
} int MinInOrder(const vector<int> &arr,int left,int right){
int result=arr[left];
for(int i=left+1;i<=right;i++){
if(result>arr[i])
result=arr[i];
}
return result;
}
};

  

(剑指Offer)面试题8:旋转数组的最小数字的更多相关文章

  1. 剑指Offer - 九度1386 - 旋转数组的最小数字

    剑指Offer - 九度1386 - 旋转数组的最小数字2013-11-24 01:57 题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转 ...

  2. 剑指offer【06】- 旋转数组的最小数字(java)

    题目:旋转数组的最小数字 考点:查找和排序 题目描述:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4, ...

  3. 《剑指Offer》算法题——“旋转数组”的最小数字

    题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减序列的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数 ...

  4. 剑指offer六之求旋转数组的最小数字

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

  5. 【剑指Offer】6、旋转数组的最小数字

      题目描述:   把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5 ...

  6. 剑指Offer:面试题8——旋转数组的最小值(java实现)

    题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入 一个递增排序的数组的一个旋转 输出 旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的 ...

  7. 剑指Offer:面试题33——把数组排成最小的数(java实现)(未完待续)

    问题描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 思路1: ...

  8. 【剑指offer】面试题 11. 旋转数组的最小数字

    面试题 11. 旋转数组的最小数字 题目描述 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4, ...

  9. Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)

    剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...

  10. 剑指Offer - 九度1504 - 把数组排成最小的数

    剑指Offer - 九度1504 - 把数组排成最小的数2014-02-06 00:19 题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输 ...

随机推荐

  1. XV6操作系统代码阅读心得(四):虚拟内存

    本文将会详细介绍Xv6操作系统中虚拟内存的初始化过程. 基本概念 32位X86体系结构采用二级页表来管理虚拟内存.之所以使用二级页表, 是为了节省页表所占用的内存,因为没有内存映射的二级页表可以不用分 ...

  2. /.nav-tabs :是普通标签页 .nav-pills:胶囊式标签页 action ;默认的激活项,给<li>加默认显示的是哪个标签页内容 .nav是标签页的一个基类,给ul加 .nav-stacked: 垂直排列BootStrap

    <meta name="viewport" content="with=device-width, initial-scale=1, user-scalabe=no ...

  3. 网页后门工具laudanum

     网页后门工具laudanum laudanum是Kali Linux预先安装的Web Shell工具.它支持多种Web后台技术,如ASP.ASP.net .JSP.PHP.Coldfusion.它提 ...

  4. BZOJ1087【状压DP】

    题目链接[http://www.lydsy.com/JudgeOnline/problem.php?id=1087] 题意:在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击 ...

  5. java 安全 技术

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 加密对应的类 是 Cipher ,意思 是加密的意思.这个类 在  javax.cryp ...

  6. [BZOJ2427][HAOI2010]软件安装(Tarjan+DP)

    2427: [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1987  Solved: 791[Submit][Statu ...

  7. LCA(最近公共祖先)--tarjan离线算法 hdu 2586

    HDU 2586 How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  8. PHPredis长连接pconnect

    1. 当使用pconnect时,连接会被重用,连接的生命周期是fpm进程的生命周期,而非一次php的执行. 疑惑1: fpm进程的生命周期是指 当前那个还是指所有:    php-fpm通常是1个ma ...

  9. Jeeplus框架中问题解决

    1,文件上传后图片显示的问题 (1)问题:在这个组件的文档介绍里面写了这个组件是有预览功能的,但是我没有找到,就自己写了这个小功能. 在框架中下图中,这个文件上传组件只能将文件上传,然后将文件名显示出 ...

  10. leetcode187. Repeated DNA Sequences

    https://leetcode.com/problems/repeated-dna-sequences/#/description   https://leetcode.com/problems/r ...