【剑指offer】07-旋转数组中的最小数字
题目:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个【非递减排序的】数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路:
二分查找法, 详情见书P83【后续自己整理思路】
class Solution: def minNumberInRotateArray(self, rotateArray): """利用二分查找""" n = len(rotateArray) first = 0 last = n-1 # 先要考虑题目中的特殊情况 if not rotateArray: return 0 if n == 1: return rotateArray[first] while first <= last: mid = (first + last) // 2 # 先看找到最小值 是什么个情况 if rotateArray[mid] < rotateArray[mid-1]: # 如果mid刚好比前面那个值小,说明mid就是最小值,∵是非递减数列 return rotateArray[mid] elif rotateArray[mid] < rotateArray[last]: # 如果mid比最后小,说明最小值在mid的左边,last游标就移动到现在mid的前面一个 last = mid - 1 else: first = mid + 1 return 0 if __name__ == '__main__': S = Solution() # 用例1:正常数组 print(S.minNumberInRotateArray([3, 4, 5, 1, 2])) # 用例2:正常数组,有重复数字 print(S.minNumberInRotateArray([4, 4, 5, 1, 2, 3])) # 用例3:边界值:升序数组 print(S.minNumberInRotateArray([3, 4, 5, 6, 7, 9])) # 用例4:边界值:只有一个数字的数组 print(S.minNumberInRotateArray([9])) # 用例5:特殊:空数组 print(S.minNumberInRotateArray([]))
引申题目(小米2019测开笔试题):
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个【排好序的】数组的一个旋转,输出旋转数组的最小元素。
例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。
其他人的代码:【后续自己整理思路】
class Solution: def minNumberInRotateArray(self, rotateArray): """利用二分查找""" n = len(rotateArray) first = 0 last = n-1 # 先要考虑题目中的特殊情况 if not rotateArray: return 0 if n == 1: return rotateArray[first] while first <= last: # # 只要范围没有缩小到只包含一个元素,就检查中间的元素 mid = (first + last) // 2 # 如果(low + high)不是偶数,Python自动将mid向下取整 if rotateArray[mid] > rotateArray[last]: # 当中间元素大于最后一个,表明最小值在右半区间 first = mid + 1 elif rotateArray[mid] < rotateArray[last]: # 当中间元素小于最后一个,表明最小值在左半区间,注意没有减一操作 last = mid else: last -= 1 # 当中间元素等于最后一个,说明没有指定的元素,将范围缩小一 return rotateArray[mid] if __name__ == '__main__': """我卡 笔试题里要有输入输出啊!""" listx = input() listy = [] for ix in listx.split(' '): listy.append(int(ix)) # 输入的数放到数组里面 S = Solution() minValue = S.minNumberInRotateArray(listy) print(minValue) # 最终结果要打印出来
笔试题里,要写输入输出!