6.查找和排序

坚强是说给别人听的谎言 提交于 2019-12-18 05:12:19

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

python方法1(遍历,复杂度O(n),直接用min或者sort函数就没意思了):

# -*- coding:utf-8 -*-
class Solution:
    # 非递减序列是后一个>=前一个
    def minNumberInRotateArray(self, rotateArray):
        if len(rotateArray) == 0:
            return 0
        for i in range(len(rotateArray) - 1):
            if rotateArray[i] > rotateArray[i + 1]:
                return rotateArray[i + 1]
        # rotateArray中只有一个元素值(包括只有一个数以及所有数相等两种情况)
        return rotateArray[0]

python方法2(二叉查找,复杂度O(logn)):

分析:二分查找变种,没有具体的值用来比较。那么用中间值和高低位进行比较,看处于递增还是递减序列,进行操作缩小范围。

处于递增:low上移

处于递减:high下移(如果是high-1,则可能会错过最小值,因为找的就是最小值)

其余情况:low++缩小范围
在这里插入图片描述
特殊情况:
在这里插入图片描述

class Solution:
    def minNumberInRotateArray(self, rotateArray):
        if len(rotateArray) == 0:
            return 0
        low = 0
        high = len(rotateArray) - 1
        while low < high:
            # 比如情况10111,加上该条件后可以满足
            if rotateArray[low] < rotateArray[high]:
                return rotateArray[low]
            mid = (low + high) // 2
            # 说明mid在第一个递增序列中(其实也可以在第二个递增序列中,这样上面语句就直接return了)
            if rotateArray[mid] > rotateArray[low]:
                low = mid + 1
            # 说明mid在第二个递增序列中
            elif rotateArray[mid] < rotateArray[high]:
                high = mid
            else:
                # 比如只有2、1两个数,low=middle=0,high=1
                low += 1
        return rotateArray[low]

c++方法1(遍历,复杂度O(n)):

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if(rotateArray.size()==0) return 0;
        for(int i=0;i<rotateArray.size()-1;i++){
            if(rotateArray[i]>rotateArray[i+1]) return rotateArray[i+1];
        }
        return rotateArray[0];
    }
};

c++方法2(二叉查找,复杂度O(logn))

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if(rotateArray.empty()) return 0;
        int low = 0;
        int high = rotateArray.size()-1;
        while(low<high){
            if(rotateArray[low]<rotateArray[high]) return rotateArray[low];
            int mid = (low + high)/2;
            if(rotateArray[mid]>rotateArray[low]){
                low=mid+1;
            }
            else if(rotateArray[mid]<rotateArray[high]){
                high=mid;
            }
            else{
                low++;
            }        
        }
        return rotateArray[low];
    }
};
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!