本题来自《剑指offer》 旋转数组中的最小数字

题目:

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

思路:

  从问题本身入手,可以看出,数据局部有序,思考数据中是否重复。属于查找范畴,顺序查找肯定可以,需要O(n)时间,数据有序可以考虑二分查找为log(n)时间内。

  若数据不重复:二分法查找

    可以局部看成两个有序的数组A、B。p1指向首,p2指向尾:

      如果中间值大于p1的值,说明最小值在B中,将p1指向中间值。

      如果中间值小于p2的值,说明最小值A中,将p2指向中间值。

      如果中间值和p1和p2的值相等,则采用下面的方法,顺序查找。

      终止条件是,当p1和p2相邻,最小值便是p2指向的值。返回即可

  若数据重复:顺序查找

    假设第一个为最小的元素,开始遍历,后面凡是小于该值的便保存,最后返回。

C++ Code:

class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
int p1 = 0;
int p2 = rotateArray.size()-1;
int mid = p1;
while (rotateArray[p1] >= rotateArray[p2]){ //循环条件首值应该大于后值
if (p2 - p1 == 1){ //当首尾相邻时候
mid = p2; //那么最小值是p2的方向
break;
}
mid = (p1 + p2)/2; //中间值为加权平均
if (rotateArray[mid]==rotateArray[p1]&&rotateArray[mid]==rotateArray[p2]){
return minInorder(rotateArray); //如果三值相等,则采用顺序查找法
}
if (rotateArray[mid] >= rotateArray[p1]){ //如果中间值大于首值,说明最小值在后面的数组中
p1 = mid; //手指针后移
}
else if (rotateArray[mid] <= rotateArray[p2]){ //如果中间值小于末值,说明最小值在前面的数组中
p2 = mid; //将末值前移
}
}
return rotateArray[mid];
}
int minInorder(vector<int> rotateArray){ //顺序查找法为O(n)
int result = rotateArray[0]; //假设最小值是首值
for (int i = 1;i<rotateArray.size();i++){
if (result >= rotateArray[i]){ //如果当找到小于该值时候,便保存
result = rotateArray[i];
}
}
return result;
}
};

Python Code:

# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
p1 = 0 #首地址
p2 = len(rotateArray)-1 #尾地址
mid = p1 #起初直接将第一个元素作为中间值,如果第一个值小于最后一个值,便直接返回
while rotateArray[p1] >= rotateArray[p2]: #循环条件是,起始的值大于末值
if p2 - p1 == 1: #终止条件是,当起始和末值相邻近
mid = p2 #将末值赋给中间返回
break
mid = (p1 + p2) // 2 #中间值是首末加权平均,python3中//是整除
if rotateArray[mid] == rotateArray[p1] and rotateArray[mid] == rotateArray[p2]:
return self.minInorder(rotateArray) #当三个值全部相等时候,说明有重复的值,采用顺序查找
if rotateArray[mid] >= rotateArray[p1]: #当中间值大于首值时候,说明最小值在后面的数组中
p1 = mid #便将首地址后移
elif rotateArray[mid] <= rotateArray[p2]: #如果中间值小于末值时候,说明最小值在前面的数组中
p2 = mid #便将末值前移
return rotateArray[mid] #其中间值便是最小的值
def minInorder(self,rotateArray): #顺序查找代码
result = rotateArray[0] #假设第一个值是最小值
if len(rotateArray): #特殊测试,测试是否为空
for i in range(len(rotateArray)-1):
if rotateArray[i] > rotateArray[i+1]: #将小于它的值保存起来
result = rotateArray[i+1]
break
return result

总结:

  从问题本身入手,明确要处理的问题是什么,要求什么样,时间和空间如何转换。以求最优。

《剑指offer》旋转数组中的最小数字的更多相关文章

  1. 剑指 Offer 03. 数组中重复的数字

    剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知 ...

  2. 菜鸟刷题路:剑指 Offer 03. 数组中重复的数字

    剑指 Offer 03. 数组中重复的数字 哈希表/set class Solution { public int findRepeatNumber(int[] nums) { HashSet< ...

  3. 5.1 剑指 Offer 03. 数组中重复的数字

    类型题:剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字.在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了, ...

  4. Go语言实现:【剑指offer】数组中重复的数字

    该题目来源于牛客网<剑指offer>专题. 在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组 ...

  5. (python)剑指Offer:数组中重复的数字

    问题描述 在长度为n的数组中,所有的元素都是0到n-1的范围内. 数组中的某些数字是重复的,但不知道有几个重复的数字,也不知道重复了几次,请找出任意重复的数字. 例如,输入长度为7的数组{2,3,1, ...

  6. [剑指offer]3.数组中的重复数字

    3.数组中的重复数字 题目 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了 ...

  7. 【剑指Offer】数组中重复的数字 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 Set 快慢指针 日期 题目地址:https://leetcod ...

  8. 剑指Offer 50. 数组中重复的数字 (数组)

    题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...

  9. 剑指offer:数组中重复的数字

    题目描述: 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度 ...

  10. [剑指Offer] 50.数组中重复的数字

    题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...

随机推荐

  1. php 调试的常用方法

    1. php 页面直接输出错误, 根据错误进行调试 2.无法通过php页面捕获到错误,通过查看apache2的日志错误进行排查,  像通过系统命令进行操作失败时,就需要日志进行查看

  2. python 微信跳一跳辅助 复现

    本来用的是苹果ios得手机,但是步骤较为复杂,没有吃透,最后妥协用了android的机器搞得. 首先找到大牛的github https://github.com/wangshub/wechat_jum ...

  3. light oj 1422 - Halloween Costumes

    题意:告诉有n场晚会中需要穿的衣服,衣服是可以套在其他衣服外面的,也就是说如果顺序为 1 2 1,那么可以将2套在1外面,第三场晚会需要穿1的时候把2脱掉即可,这样就只需要穿两次衣服.题目是再告诉了顺 ...

  4. linux 下为qtcreator 添加排版工具

    1. 下载astyle.   http://sourceforge.net/projects/astyle 这里可以下载最新版本, 目前是3.1  下载文件astyle_3.1_linux.tar.g ...

  5. Eclipse下egit插件的使用

    接触GIT已经很久了,但碰到的公司一直都在使用SVN,并因为各种理由拒绝换成GIT.今年换了份工作,乘着搭建公司新框架和项目的机会,总算在正式项目上使用了GIT.GIT的服务器直接就用了https:/ ...

  6. Django 的系统时区设置 RPC

    PRC   Deprecated +08:00 +08:00 Link to Asia/Shanghai settings.py  文件的设置项:   TIME_ZONE = 'PRC'     来源 ...

  7. 最长增长子序列(LIS)

    给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4. 说 ...

  8. MongoDB 的 upsert

    MongoDB 的update 方法的三个参数是upsert,这个参数是个布尔类型,默认是false.当它为true的时候,update方法会首先查找与第一个参数匹配的记录,在用第二个参数更新之,如果 ...

  9. 二层环路保护,SEP多实例的配置

    作者:邓聪聪 智能以太保护SEP(Smart Ethernet Protection)是一种专用于以太网链路层的环网协议.SEP是一种以太环路保护机制,它通过有选择性地阻塞网络环路冗余链路,来达到消除 ...

  10. Windowns下使用SecuretCRT编写脚本增加高亮

    作者:邓聪聪 secureCRT设置高亮1)修改环境变量:export TERM=xterm-color 2)增加VIM高亮:vim ~/.vimrc   set syntax=on colorsch ...