zoukankan      html  css  js  c++  java
  • 剑指offer-JZ6

    题目描述

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

    输入

    复制
    [3,4,5,1,2]

    返回值

    复制
    1

    思路:

    1.二分:

      根据题意我们可以知道,给出的数组可以被视为由一个(未旋转)或两个(发生选择)非递减数组组成。

      定义ps为数组开始下标,pe为数组结束下标,mid=(ps+pe)/2

      那么:如果array[mid] >= array[pe],则最小值一定在mid右侧

         如果array[mid] <= array[ps],则最小值一定为mid或在mid左侧

      这样我们就可以在迭代求解时,每次都将问题规模缩小一半,进而缩短时间。

      我们可以递归的实现:

    class Solution {
    public:
        int minNumberInRotateArray(vector<int> rotateArray) {
            int len = rotateArray.size();
            if(len == 0)
                return 0;
            int minn = Solve(rotateArray,0,len-1);
            return minn;
        }
          
        int Solve(vector<int> rotateArray, int ps, int pe)
        {
            if(ps >= pe)
                return rotateArray[ps];
            int mid = (ps+pe)/2;
            int right_n = rotateArray[ps], left_n = rotateArray[ps];
            if(rotateArray[mid] >= rotateArray[pe])
            {
                right_n =  Solve(rotateArray,mid+1,pe);
            }
            else if(rotateArray[mid] <= rotateArray[ps])
            {
                left_n =  Solve(rotateArray,ps,mid);
            }
            return min(right_n,left_n);
        }
    };
    View Code

      也可以非递归的实现:

    class Solution {
    public:
        int minNumberInRotateArray(vector<int> rotateArray) {
            int len = rotateArray.size();
            if(len == 0)
                return 0;
            int minn = Solve(rotateArray,0,len-1);
            return minn;
        }
          
        int Solve(vector<int> rotateArray, int ps, int pe)
        {
            int ans = rotateArray[ps];
            while(ps < pe)
            {
                int mid = (ps+pe)/2;
                if(rotateArray[mid] >= rotateArray[pe])
                {
                    ps = mid+1;
                }
                else
                {
                    pe = mid;
                }
            }
            ans = min(ans,rotateArray[ps]);
            return ans;
        }
    };
    View Code

    2.暴力:

      暴力最容易想到的思路,但是如果裸暴力你可能剑指不到offer

      假设最小值为minn,对于array[k]==minn,肯定存在k使得array[k] < array[k-1](特殊情况除外:数组未发生旋转或数组内所有元素大小相同)

      我们同时从数组的两端寻找这样的k值即可,实现时有些小技巧来帮助我们节省时间

    static const auto _=[](){
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        return nullptr;
    }();
    class Solution {
    public:
        int minNumberInRotateArray(vector<int> rotateArray) {
            for(int i=0,j=rotateArray.size()-1;i<j;i++,j--){
                if(rotateArray[i]>rotateArray[i+1]) return rotateArray[i+1];
                if(rotateArray[j]<rotateArray[j-1]) return rotateArray[j];
            }
            return rotateArray.empty()?0:rotateArray[0];
        }
    };
    View Code
  • 相关阅读:
    Linux中创建Daemon进程的三种方法【转】
    Linux 内核定时器使用 二 高精度定时器 hrtimer 的用例【转】
    使用 Qemu 虚拟 ARM64 平台演示 kdump 崩溃转存【转】
    自旋锁 spin_lock、 spin_lock_irq 以及 spin_lock_irqsave 的区别【转】
    Linux中的spinlock机制[四]
    Linux中的虚拟内存机制和内存映射【转】
    那些情况该使用它们spin_lock到spin_lock_irqsave【转】
    Linux内核中的软中断、tasklet和工作队列详解【转】
    Linux 读写memory操作,devmem直接访问物理内存地址【转】
    Linux性能之DVFS/cpufreq【转】
  • 原文地址:https://www.cnblogs.com/alan-W/p/14226707.html
Copyright © 2011-2022 走看看