zoukankan      html  css  js  c++  java
  • 【剑指Offer】05旋转数组的最小数字

    题目描述

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

    时间限制:1秒;空间限制:32768K;本题知识点:查找

    解题思路

    思路一

    首先考虑数组长度为0和1的情况,然后考虑数组元素全部相等的情况,除上述情况外从头到尾遍历数组,只要搜索到后一个元素比前一个小,后一个数即是旋转数组的最小元素。这种做法的时间复杂度为O(n)。python代码:

    # -*- coding:utf-8 -*-
    class Solution:
        def minNumberInRotateArray(self, rotateArray):
            # write code here
            if len(rotateArray) == 0:   #数组长度为0的情况
                return 0
            elif len(rotateArray) == 1: #数组长度为1的情况
                return rotateArray[0]
            for i in range(len(rotateArray)-1):
                if rotateArray[i]>rotateArray[i+1]:
                    return rotateArray[i+1]
            return rotateArray[0]       #数组元素全部相等的情况

    思路二

    再来看这道题目有个特点,旋转之后的数组实际上可以划分成两个有序的子数组,而最小的元素就是两个子数组的分界线。比较好的思路是用二分查找,也可能是面试官考核的出发点。这种做法的时间复杂度为O(logn)

    思路如下:

    (1)用两个指针left,right分别指向数组的第一个元素和最后一个元素。

    (2)找到数组的中间元素mid。

    (3)比较left元素和mid元素的大小,首先考虑元素无重复的情况。

    • 如果left元素比mid元素小,则说明mid元素在后一个有序的子数组中,此时最小元素位于mid元素的前面,我们可以让指针right指向中间元素mid;
    • 如果left元素比mid元素大,则说明mid元素在前一个有序的子数组中,此时最小元素位于mid元素的后面,我们可以让指针left指向中间元素mid;
    • 循环直到左右指针相邻,最终left指针将指向前面数组的最后一个元素,right指针指向后面数组中的第一个元素,而right指针指向的刚好是最小的元素。

    (4)考虑元素重复的情况,若出现left,right,mid元素均相等的情况如 {1,0,1,1,1} 则无法进行二分查找,改用顺序查找。

    # -*- coding:utf-8 -*-
    class Solution:
        def minNumberInRotateArray(self, rotateArray):
            # write code
            left = 0
            right = len(rotateArray)-1
            if len(rotateArray)==0:
                return 0
            while ((right - left) != 1):
                mid = (left + right) / 2 #整除
                # 中间数和左指针、右指针都相同
                if rotateArray[mid] == rotateArray[left] and rotateArray[right]:
                    return min(rotateArray)
                if rotateArray[left] < rotateArray[mid]:
                    left = mid
                else:
                    right = mid
            mid = right
            return rotateArray[mid]

    思路三

    最后,分享一个比较bug的做法,能通过但是面试官一定不想给你offer。。。

    # -*- coding:utf-8 -*-
    class Solution:
        def minNumberInRotateArray(self, rotateArray):
            # write code
            if rotateArray:
                return min(rotateArray)
            else:
                return 0
  • 相关阅读:
    Celery异步框架
    彻底理解cookie,session,token
    消息队列
    pip源、搭建虚拟环境、git
    全文检索
    redis高级
    redis基础
    基本数据结构和算法(python代码实现算法)
    MySQL数据库高级
    MySQL数据库进阶
  • 原文地址:https://www.cnblogs.com/yucen/p/9912056.html
Copyright © 2011-2022 走看看