• 《剑指offer》旋转数组中的最小数字


    本题来自《剑指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

    总结:

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

  • 相关阅读:
    TCP拥塞控制算法纵横谈-Illinois和YeAH
    精度解析百思不得姐流行框架之精华版
    3D物体识别的如果检验
    Android内存泄漏检測与MAT使用
    Android学习——在Android中使用OpenCV的第一个程序
    virtio-netdev 数据包的发送
    【剑指Offer学习】【面试题23:从上往下打印二叉树】
    纵谈进程枚举
    《谈学单片机有前途还是嵌入式系统有前途》一文吴坚鸿回复整理
    结构类模式(七):代理(Proxy)
  • 原文地址:https://www.cnblogs.com/missidiot/p/10761415.html
Copyright © 2020-2023  润新知