面试题8-旋转数组的最小值

递增数组前几个元素依次挪到尾部--递增数组的旋转数组(部分有序,前后两部分分别有序)

考虑特殊:

1.数组为空

2.递增数组将前0个元素挪到尾部--完全有序,纯递增数组--最小值即为首元素

正常处理递增数组的旋转数组:

3.首尾元素相邻,时,最小值即为尾元素,跳出函数,返回最小值

1.数组中相邻某几个元素增量为0--b=[3,4,5,6,9,0,1,2,3,3]-可作为正常处理,依次缩小范围,直到3

2.数组中首、尾、中间值三者相同--【1,1,1,0,1】,部分有序已经打乱了,无法判断该缩小范围至那部分,改用顺序查找

 

  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Sat Feb 18 10:27:53 2017
  4. @author: zzpp220
  5. """
  6. '''二分查找适合一个 已经全部排序(或部分排序)的数组中,查找数字或统计数字出现的次数'''
  7. classMin_Rotate:
  8.    def __init__(self,array):
  9.        self.array=array
  10.    defFind_Min(self):
  11.        ifnot self.array:
  12.            returnNone
  13.            
  14.        first_index=0
  15.        last_index=len(self.array)-1
  16.        ##看首尾大小,满足条件的话,确定是旋转数组(首>=尾)
  17.        while self.array[first_index]>=self.array[last_index]:
  18.            ##采用二分法进行查找
  19.            mid_index=(first_index+last_index)/2
  20.            ##跳出该循环的条件,当层层缩小后last_index,first_index为相邻元素时,则last为最小(旋转了)
  21.            if last_index-first_index==1:
  22.                return self.array[last_index]
  23.             ##首尾和中间元素全相等,情况特殊(首=中=尾),已经不满足排序的条件(不管是全部还是部分)只能改用顺序查找,该函数直接返回顺序查找的结果  
  24.            if self.array[last_index]==self.array[first_index]and self.array[mid_index]==self.array[first_index]:
  25.                return self.Min_Inorder()#(first_index,last_index)
  26.             ##除去上面的特殊情况,判断中间元素与首、尾元素的关系,看要缩小至哪一半范围,循环如此
  27.             #如果中间值大于首值,说明处于前面的递增序列,则最小值在中间值的后面,选择后半部分继续查找  
  28.            if self.array[mid_index]>=self.array[first_index]:
  29.                first_index=mid_index
  30.                #如果中间值小于尾值,说明处于后面的递增序列,则最小值要么为中间值,要么比中间值还小在中间值的前面,选择前半部分继续查找
  31.            elif self.array[mid_index]<=self.array[last_index]:
  32.                last_index=mid_index
  33.         ##首尾元素大小不满足,说明首小于尾,升序(即把递增数组的前0个元素搬到后面去了)是特例,首元素为最小      
  34.        return self.array[first_index]
  35.    ##顺序查找,基于递增序列旋转数组的特点,首个小于value的值即为最小值。如一直没有,则说明最小值即为value
  36.    defMin_Inorder(self):
  37.        value=self.array[0]
  38.        return[self.array[i]for i in range(1,len(self.array)-1)if self.array[i]< value]
  39.        return value
  40. #==============================================================================
  41. #     def Min_Inorder(self,first_index,last_index):
  42. #         value=self.array[first_index]
  43. #         return [self.array[i] for i in range(first_index+1,last_index) if self.array[i] < value]
  44. #         return value
  45. #==============================================================================
  46. a=[3]
  47. b=[3,4,5,6,9,0,1,2,3,3]
  48. c=[1,1,1,1,0,1,1,1]
  49. d=[2,3,6,8,9,12]
  50. e=[5,6,7,2,4,5,5]
  51. f=None
  52. solution=Min_Rotate(b)
  53. print solution.Find_Min()
程序中独立出的 Min_Inorder 也可以直接放到主程序中,反正就几句话。见附件。

 

附件列表

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值