题目:

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

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

例如数组{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. Mutex 的正确打开方式

    在使用 Mutex 在给线程/进程间加锁时,需要注意的问题. 1 AbandonedMutexException 在使用 mutex.WaitOne 时,可能抛出异常 AbandonedMutexEx ...

  2. apue第17章笔记

    unix domain socket 关闭socket并不会删除文件,重复bind会失败.所以在bind之前要unlink该文件. open服务器的实现只是简单地看了一下,大致上就是通过unix do ...

  3. linux——(6)vim与vi

    概念:vi与vim的区别 vi是一款老式的文字处理软件,不过现在依然广泛使用,所有的UnixLike系统都会内置vi文本编辑器. vim可以看出vi的升级版,不过vi更像是一个程序开发工具,功能也比v ...

  4. [BZOJ4032][HEOI2015]最短不公共子串(Trie+DP)

    在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之——被它们虐. 操作一:对A,B分别建SAM,暴力BFS. 操作二:对B建序列自动机或SAM,A在上面暴力匹配. 操作三:对A,B建 ...

  5. [BZOJ4869][六省联考2017]相逢是问候(线段树+扩展欧拉定理)

    4869: [Shoi2017]相逢是问候 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1313  Solved: 471[Submit][Stat ...

  6. Every-SG 博弈论 mark定义和结论

    http://blog.sina.com.cn/s/blog_51cea4040100h3l9.html 这种类型,可以想成这样,有N组游戏,有N个穿红色衣服的人代表先手,有N个穿蓝色衣服的人代表后手 ...

  7. 莫队p2 【bzoj3809】Gty的二逼妹子序列

    发现一篇已经够长了...所以就放在这里吧... http://hzwer.com/5749.html ↑依然是看大牛题解过的   袜子那道题太简单了.... 然后被这道题超时卡了一段时间....... ...

  8. [COGS2426][HZOI 2016]几何

    [COGS2426][HZOI 2016]几何 题目大意: 给定平面坐标系内\(n\)个整点,求这些整点能构成的正多边形的边数的最大值. 思路: 一个基本结论:平面直角坐标系内能够形成的正多边形一定是 ...

  9. [转]JSP或servlet中(以及上传下载文件)中文乱码或不显示的解决方案

    时间 2014-04-14 14:33:44  CSDN博客 原文  http://blog.csdn.net/xby1993/article/details/23677375 主题 ServletJ ...

  10. C# 7.0中可能出现的语法

    今天在MSDN上看到的微软关于微软关于C# 7.0特性的Work List,主要特性如下: Tuple增强 Tuple的可读性一直不是很好, 很多时候宁愿新写一个类也不使用Item1, Item2这种 ...